소스 lib/*가 작동하지 않는 이유는 무엇입니까?

소스 lib/*가 작동하지 않는 이유는 무엇입니까?

다음과 같은 폴더 구조를 가진 작은 프로그램이 있습니다.

- main.sh
- lib/
  - clean.sh
  - get.sh
  - index.sh
  - test.sh

각 파일에는 i 가 포함되어 있습니다 main.sh.

main.sh:

source lib/*

get_products
clean_products
make_index
test_index

위의 예에서 처음 두 함수는 작동하지만 마지막 두 함수는 작동하지 않습니다.

하지만 다음으로 바꾸면 source lib/*:

source lib/get.sh
source lib/clean.sh
source lib/index.sh
source lib/test.sh

모든 것이 예상대로 작동합니다.

source lib/*이것이 예상대로 작동하지 않는 이유를 아는 사람이 있습니까 ?

답변1

Bash의 source내장 명령은 단일 파일 이름만 사용합니다.

source filename [arguments]

첫 번째 인수 이외의 모든 인수는 위치 인수가 됩니다 filename.

간단한 예:

$ cat myfile
echo "param1: $1"
$ source myfile foo
param1: foo

모든 출력help source

source: source filename [arguments]

Execute commands from a file in the current shell.

Read and execute commands from FILENAME in the current shell.  The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.

Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.

.(이는 특히 POSIX이므로 이식성이 더 좋은 내장된 "포인트 소스"에도 적용됩니다 .)

당신이 보고 있는 겉보기에 모순된 동작에 대해서는 완료 후 main.sh를 실행해 볼 수 있습니다 set -x. 어떤 명령문이 언제 실행되었는지 확인하면 단서를 얻을 수 있습니다.

답변2

배쉬 문서source단일에 적용됨 을 나타냅니다.파일 이름:

. (일정 기간)

.파일 이름[논쟁]

다음에서 명령을 읽고 실행합니다.파일 이름현재 쉘 컨텍스트의 매개변수입니다. 만약에파일 이름...

그리고 소스코드...원천...이를 지원합니다:

result = source_file (filename, (list && list->next));

source_file정의는 어디에 있습니까?evalfile.c부르다 _evalfile:

rval = _evalfile (filename, flags);

그리고 _evalfile파일만 엽니다.

fd = open (filename, O_RDONLY);

답변3

보완적인레이어 b에 대한 유용한 답변, 확장하려는 유형의 파일이 존재하는지 확실하지 않은 경우 욕심 많은 전역 확장을 사용하지 않는 것이 좋습니다.

다음을 수행하면 (확장자 없음) 파일이 실행될 수 있는 유해한 명령(예: 실행 권한이 있다고 가정)이 .sh포함된 임시 파일인 것처럼 보일 수 있습니다.rm -rf *

source lib/*

따라서 *.sh파일을 개별적으로 반복할 수 있더라도 항상 전역 확장을 위해 적절한 바인딩 세트를 사용하십시오.

for globFile in lib/*.sh; do
    [ -f "$globFile" ] || continue
    source "$globFile"
done

이는 현재 폴더에 일치하는 전역 패턴이 없는 경우 [ -f "$globFile" ] || continue루프에서 반환되며 , 이는 셸의 확장 셸 옵션과 동일합니다.nullglobbash

관련 정보