다른 스크립트에서 사용할 수있는 Bash 함수를 정의하는 방법


13

파일에 bash함수를 정의했습니다 ~/.bashrc. 이를 통해 쉘 터미널에서 사용할 수 있습니다. 그러나 스크립트 내에서 호출 할 때 존재하지 않는 것 같습니다.

bash스크립트에서 사용할 함수를 어떻게 정의 할 수 있습니까?


그러나 내 .bash_profile은 기본적으로 .basrc 파일을 읽으므로 로그인 또는 비 로그인 셸을 사용하더라도 결과가 동일 할 것으로 기대합니다.
Onturenio

/bin/shshebang 라인에서 사용 하고 있습니까?
케빈

답변:


9

~/.bash_profile~/.bashrc스크립트에서 읽을 수 있으며, 기능은 기본적으로 내 보내지 않습니다. 그렇게하려면 다음 export -f과 같이 사용할 수 있습니다 .

$ cat > script << 'EOF'
#!/bin/bash
foo
EOF
$ chmod a+x script
$ ./script
./script: line 2: foo: command not found
$ foo() { echo "works" ; } 
$ export -f foo
$ ./script
works

export -f foo~/.bash_profile로그인 후 스크립트에서이 기능을 사용할 수 있도록 호출 할 수도 있습니다 . 경고export -f휴대 수 없다는 .

더 나은 해결책은을 사용하여 함수가 포함 된 파일을 소스로 만드는 것 . file입니다. 이는 훨씬 이식성이 뛰어나며 특정 방식으로 환경을 설정하는 데 의존하지 않습니다.


function myFunction { ... }in ~/.bash_profile과 같은 함수를 선언하면 좋을까요?
amphibient

함수를 사용하여 파일을 소싱하는 것과 관련하여 귀하의 대답을 올바르게 이해했다면 모든 스크립트에서 파일을 명시 적으로 제공해야한다는 것을 의미합니다. 이것은 모든 스크립트에서 함수 자체를 복사하여 붙여 넣는 것보다 덜 복잡하지 않습니다. 나는 몇 줄을 절약 할 것이지만, 그게 전부입니다. 그러나 export솔루션이 제대로 작동하는 것 같습니다. 감사.
Onturenio

@ foampile, 이것은 정확하게 내가 한 일이며 스크립트에서 함수를 호출 할 때 작동하지 않습니다.
Onturenio

1
@ Onturenio : @ chris-down이 제안한 두 번째 방법이 실제로 더 좋습니다 .1) 누군가가 스크립트를 읽을 때 일부 foo기능 이 필요하다는 것을 알고 file있습니다 .2) file호출 쉘을 확인하는 것보다 내용을 더 잘 제어 할 수 있습니다 foo스크립트를 호출하기 전에 변경되지 않았습니다 . file예를 들어, 안전 점검을 추가 하여 변경되지 않았는지 확인할 수 있습니다 . (쉽지는 않지만 가능합니다). (음, 정의 된 foo 함수에 대한 검사를 수행 할 수도 있지만 드리프트를 얻습니다 ^^ 방법 2가 더 깨끗하다고 ​​생각합니다.) 3) file더 이상 필요한 것은 포함하지 않습니다.
Olivier Dulac

8

.bashrc대화식 쉘에서만 읽습니다. (실제로, 그것은 지나치게 단순화 된 것입니다 : bash는 이와 관련하여 기발합니다. Bash는 .bashrc로그인 쉘이거나 대화 형인지 여부를 읽지 않으며 예외도 예외가 있습니다 .bash의 부모 프로세스가 rshd또는 sshd이면 bash는 읽습니다 .bashrc. 대화식인지 아닌지)

함수 정의를 알려진 위치의 파일에 넣고 .(또한 철자법 source) 내장을 사용하여 해당 파일을 스크립트에 포함하십시오.

$ cat ~/lib/bash/my_functions.bash
foo () {

$ cat ~/bin/myscript
#!/bin/bash
. ~/lib/bash/my_functions.bash
foo bar

원하는 경우 ksh의 자동로드 기능을 수행 할 수 있습니다. 각 함수 정의를 함수와 동일한 이름의 파일에 넣으십시오. FPATH변수에 함수 정의가 포함 된 디렉토리를 나열하십시오 (콜론으로 구분 된 디렉토리리스트). 다음은 ksh에 대한 대략적인 근사치입니다. autoload실제로 주문형 대신 함수를 즉시로드합니다.

autoload () {
  set -- "$(set +f; IFS=:;
            for d in $FPATH; do
              if [ -r "$d/$1" ]; then echo -E "$d/$1"; break; fi;
            done)"
  [[ -n $1 ]] && . "$1"
}

자동로드의 경우 +1이지만 bash와 함께 제공되는 것을 사용하는 것이 좋습니다. 최신 버전은 지연로드를 지원합니다.
불가사리

0

기능 이 필요 하십니까 ? 그렇지 않은 경우 논리를에서 별도의 독립형 Bash 스크립트로 가져 오는 것을 고려하십시오 $PATH. 예를 들어, 나는 이것을 내 ~/.bashrc:

# echo public IP address
alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

~/bin내에 $PATH있으므로 ~/bin/wanip다음 내용으로 만들었습니다 .

#!/bin/bash

# echo public IP address
dig +short myip.opendns.com @resolver1.opendns.com

그리고 chmod 0755 ~/bin/wanip그것을 실행 가능하게 만들었습니다. 이제 wanip다른 스크립트에서 실행할 수 있습니다 .

내가 가진 같은 wanip독립형 배쉬 스크립트. 이 논리를 일반적으로 사용할 수 있기를 바랍니다 (현재 대화 형 Bash 세션 외에도). 이 스크립트는 논리와 문서를 훌륭하게 캡슐화합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.