어떻게 하나를 선택할 않습니다 "$0"
및"${BASH_SOURCE[0]}"
GNU 의이 설명 은 저에게별로 도움이되지 않았습니다.
BASH_SOURCE
An array variable whose members are the source filenames where the
corresponding shell function names in the FUNCNAME array variable are
defined. The shell function ${FUNCNAME[$i]} is defined in the file
${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}
답변
참고 : POSIX 호환 솔루션의 경우이 답변을 참조하십시오 .
${BASH_SOURCE[0]}
(또는 간단히 $BASH_SOURCE
[1]
)에는 모든 호출 시나리오 에서 포함하는 스크립트의 (잠재적으로 상대적인) 경로가 포함되어 있습니다. 특히 스크립트가 소싱 된 경우에도 $0
.
또한 Charles Duffy가 지적했듯이 호출자 $0
는 임의의 값 으로 설정할 수 있습니다 .
반대로 이름이 지정된 파일이 없으면 비워 둘 $BASH_SOURCE
수 있습니다. 예 :
echo 'echo "[$BASH_SOURCE]"' | bash
다음 예는이를 설명합니다.
스크립트 foo
:
#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"
$ bash ./foo
[./foo] vs. [./foo]
$ ./foo
[./foo] vs. [./foo]
$ . ./foo
[bash] vs. [./foo]
$0
BASH_SOURCE
이름에서 알 수 있듯이 는 POSIX 셸 사양의 일부인 반면는 Bash 전용입니다.
[1] 선택 읽기 : ${BASH_SOURCE[0]}
vs.$BASH_SOURCE
:
배시는 기준 소자를 허용 0
의 배열 하여 변수 라 표기 대신 기입 ${arr[0]}
하면 쓸 수있다 $arr
; 즉, 변수 가 스칼라 인 것처럼 참조하면 index에있는 요소를 얻습니다 0
.
이 기능을 사용 $arr
하면 배열 이라는 사실이 모호해 지므로 인기있는 쉘 코드 linter shellcheck.net 에서 다음 경고를 발행합니다 (이 글을 쓰는 시점에서).
SC2128 : 인덱스없이 배열을 확장하면 첫 번째 요소 만 제공됩니다.
참고 :이 경고는 도움이되지만 더 정확할 수 있습니다. 첫 번째 요소를 반드시 얻을 필요는 없기 때문 입니다. 특히 0
반환 되는 인덱스의 요소 이므로 첫 번째 요소에 더 높은 인덱스가있는 경우- Bash에서 가능합니다-당신은 빈 문자열을 얻게 될 것입니다; 시도해보십시오 'a[1]='hi'; echo "$a"'
.
(반면에 zsh
, 어느 배신자는 실제로 수행 색인에 관계없이 최초의 요소를 리턴).
실용적으로 말하면, 당신은 인해 무명이 기능을 피하다하도록 선택할 수 있습니다, 그러나 예상 작동하고, 당신은 거의 경우 이제까지 접근 필요와 indices없는 것 , 다른 것보다 0
배열 변수의 ${BASH_SOURCE[@]}
.
답변
이 스크립트는 설명하는 데 도움이 될 수 있습니다. 외부 스크립트는 내부 스크립트를 호출하는 중간 스크립트를 호출합니다.
$ cat outer.sh
#!/usr/bin/env bash
./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './inner.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = ''
$BASH_SOURCE[2] = ''
그러나 스크립트 호출을 source
문으로 변경하면 :
$ cat outer.sh
#!/usr/bin/env bash
source ./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
source ./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './outer.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = './middle.sh'
$BASH_SOURCE[2] = './outer.sh'
답변
이식성을 위해 ${BASH_SOURCE[0]}
정의 된 경우 사용하고 $0
그렇지 않은 경우 사용하십시오. 그것은 준다
${BASH_SOURCE[0]:-$0}
특히, zsh에서 스크립트가 source
d 인 경우에도 $ 0에는 올바른 파일 경로가 포함되어 있습니다 .