소스 bash 스크립트에 잘못된 $BASH_SOURCE 값이 포함되어 있습니까?

소스 bash 스크립트에 잘못된 $BASH_SOURCE 값이 포함되어 있습니까?

Linux 문서화 프로젝트설명하다:

파일을 가져오면(명령줄에 소스 파일 이름 또는 .filename을 입력하여) 파일의 코드 줄이 명령줄에 인쇄된 것처럼 실행됩니다. 이는 파일에 저장하고 해당 파일을 가져와서 불러올 수 있는 복잡한 프롬프트에 특히 유용합니다.

test.sh, test2.sh및 의 세 가지 스크립트가 있습니다 common.sh. 현재 스크립트의 기본 이름이 포함된 변수를 common.sh설정합니다 ( 사용 ). 호출되어 표시됩니다. 호출되고 표시되는 내용.$me${BASH_SOURCE[0]}test.shsourcecommon.sh$metest2.shevalcommon.sh$me

==> common.sh <==
#!/bin/bash

realpath=$(realpath "${BASH_SOURCE[0]}")
me=$(basename "${realpath}")

==> test.sh <==
#!/bin/bash

source common.sh

echo "me: $me"

==> test2.sh <==
#!/bin/bash

common=$(cat common.sh)
eval "$common"

echo "me: $me"

실행하면 ./test2.sh출력은 입니다 me: test2.sh.

실행하면 ./test.sh출력은 입니다 me: common.sh.왜 그럴까요?

편집하다

sourcingJeff Schaller의 대답은 다른 스크립트가 스크립트 이름을 배열로 "취소"한다는 점에서 정확합니다 $BASH_SOURCE. 바라보는 것만으로도 내가 원하는 것을 이룰 수 있었다마지막값은 $BASH_SOURCE아래를 참조하세요.

#!/bin/bash

declare -p BASH_SOURCE
bash_source_size="${#BASH_SOURCE[*]}"
realpath=$(realpath "${BASH_SOURCE[$bash_source_size-1]}")
me=$(basename "${realpath}")

답변1

test.sh호출 되면 sourcebash는 common.sh현재 스크립트를 명시적으로 가져와 BASH_SOURCE변수를 업데이트합니다. test2.sh명령 대체(무엇이든 가능) 및 후속 명령을 실행할 때 eval명시적인 일은 sourcing발생하지 않으므로 BASH_SOURCE는 영향을 받지 않습니다.

쉘 스크립트 감지

declare -p BASH_SOURCE차이점을 확인하는 라인:

$ ./test.sh
declare -a BASH_SOURCE='([0]="common.sh" [1]="./test.sh")'
declare -a BASH_SOURCE='([0]="./test.sh")'
me: common.sh

비교:

$ ./test2.sh
declare -a BASH_SOURCE='([0]="./test2.sh")'
declare -a BASH_SOURCE='([0]="./test2.sh")'
me: test2.sh

bash가 아는 한 에서는 test2.sh임의의 명령, 즉 $(echo ls).

관련 정보