왜 'BASH_SOURCE'를 사용하여 스크립트가 실행되는 현재 디렉터리를 가져올 수 있나요?

왜 'BASH_SOURCE'를 사용하여 스크립트가 실행되는 현재 디렉터리를 가져올 수 있나요?

source( .)를 사용하여 $HOME/.bash_profile로컬 파일에서 명령을 실행합니다 $HOME/.dotfiles/.bash_profile.

[[ -r "$HOME/.dotfiles/.bash_profile" ]] && . "$HOME/.dotfiles/.bash_profile" 

이제 $HOME/.dotfiles/.bash_profilein $0값 은 입니다. 이는 실행 중인 스크립트의 현재 디렉터리를 검색 "-bash"하는 데 사용할 수 없음을 의미합니다 .dirname

BASH_SOURCE실행 스크립트의 이름으로 채워져야 한다는 것을 읽었습니다 (그리고 작동합니다!).

하지만실행 스크립트를 쉘 함수에 해당하는 소스 파일 이름의 배열로 정의하면 BASH_SOURCE실행 스크립트 이름이 저장되나요?man bash

또한 BASH_SOURCE배열로 정의되어 있으므로 스크립트가 실행되는 현재 디렉터리를 검색하기 위해 다음과 같이 사용하는 것은 여러 값을 보유할 수 있으므로 안전하지 않습니다 dirname $BASH_SOURCE.

man bash:

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]}.

답변1

그런데 BASH_SOURCE실행 스크립트가 쉘 함수에 해당하는 소스 파일 이름의 배열로 man bash에 정의되어 있는데 왜 실행 스크립트 이름을 저장해야 할까요?

왜? 아마도 메인 스크립트의 파일 이름을 사용하는 것이 유용하기 때문일 것입니다.

매뉴얼의 설명을 살펴 보겠습니다.

BASH_SOURCE
FUNCNAME배열 변수에 해당 쉘 함수 이름을 정의하는 소스 파일 이름이 멤버인 배열 변수입니다. 쉘 함수는 ${FUNCNAME[$i]}파일에 정의되어 ${BASH_SOURCE[$i]}있으며 다음에서 파생됩니다.${BASH_SOURCE[$i+1]}

FUNCNAME
현재 실행 중인 호출 스택에 있는 모든 셸 함수의 이름을 포함하는 배열 변수입니다. 인덱스 0의 요소는 현재 실행 중인 쉘 함수의 이름입니다. 맨 아래 요소(인덱스가 가장 높은 요소)는 "main"입니다.

foo기본 스크립트에서 호출되는 함수에는 정의된 파일 이름을 ${FUNCNAME[0]}포함 foo하고 포함합니다 . 기본 스크립트 파일의 이름을 포함 합니다 .${BASH_SOURCE[0]}foo${FUNCNAME[1]}main${BASH_SOURCE[1]}

for FUNCNAME, 함수 외부에서 비어 있음을 명시적으로 나타냅니다. 왜냐하면 BASH_SOURCE그것은 다르기 때문입니다. 항상 기본 스크립트 파일 이름의 확장자를 끝에 추가하는 것이 BASH_SOURCE다소 논리적입니다 . 함수 호출 및 반환에는 앞에 요소를 추가/제거하기만 하면 됩니다.

그렇게 말하지는 않지만 BASH_SOURCE소스 스크립트( . foo.sh또는 유사한 것)도 추적합니다. FUNCNAME또한 함수가 호출되지 않는 한 표시되지 않지만 source앞에 실제 함수가 있을 때 표시됩니다.

또한 BASH_SOURCE배열로 정의되어 있으므로 스크립트가 실행되는 현재 디렉터리를 검색하기 위해 다음과 같이 사용하는 것은 여러 값을 보유할 수 있으므로 안전하지 않습니다 dirname $BASH_SOURCE.

이것이 질문인지 진술인지 잘 모르겠습니다. 하지만 인덱스 없이 배열을 참조하는 것은 인덱스를 사용하는 것과 같습니다 0. $BASH_SOURCE이는 또한 true이며 ${BASH_SOURCE[0]}현재 함수가 정의된 파일의 이름을 포함합니다. (비슷한 것이 필요하기 때문에 기본 스크립트용이 아닙니다 ${BASH_SOURCE[ ${#BASH_SOURCE[@]} - 1 ]}.)

파일 이름은 여전히 ./foo.sh​​또는 와 유사할 수 foo.sh있으므로 dirname유용한 정보를 제공하지 못할 수 있습니다.

관련 정보