디렉토리의 모든 스크립트를 현재 쉘 세션에 어떻게 포함시킬 수 있습니까?

디렉토리의 모든 스크립트를 현재 쉘 세션에 어떻게 포함시킬 수 있습니까?

일부 스크립트 파일이 포함된 디렉터리가 있습니다.

/scripts
    api.sh
    time.sh
    certificate.sh
    docker.sh
    nginx.sh
    wifi.sh
    ...

이 스크립트는 명령이 아닙니다. 단지 몇 가지 기능만 포함되어 있을 뿐입니다. 그래서 추가 /script하고 $PATH실행할 수 없습니다 . 예를 들면 api.sh다음과 같은 내용이 있습니다.

function isApi()
{
   # body
}

function resetApi()
{
   # body
}

function testDatabase()
{
   # body
}

현재 세션에 포함시킨 다음 해당 기능을 호출해야 합니다.

하나씩 포함시키면 . /scripts/x.sh해당 기능을 사용할 수 있습니다.

그러나 bash 스크립트를 실행 loadScripts.sh하여 로드하면 작동하지 않습니다.

find /scripts -mindepth 1 |
while read scriptFile;
do
    echo $scriptFile
    source $scriptFile
done

현재 세션에 디렉터리의 모든 스크립트를 어떻게 포함시킬 수 있나요?

답변1

오직:

for script in scripts/*.sh; do
  . "$script"
done

특수 .sh 내장은 쉘에게 제공된 파일의 코드를 평가하도록 지시합니다. csh에는 source유사한 명령이 있으며 일부 쉘은 bash두 명령을 모두 지원하며 .때로는 source의미가 약간 다릅니다.

.또한 / on 을 사용해야 합니다. 이렇게 하면 스크립트를 해석하기 위한 새 셸이 시작되므로 함수는 호출 셸이 아닌 해당 임시 셸에서 정의됩니다.sourceloadScripts.sh./loadScripts.sh

또한 예를 들어 현재 작업 디렉터리에서 if를 실행하여 / 에 전달된 경로에 a 가 포함되어 있는지 확인하세요 /. 그렇지 않으면 해당 경로를 찾을 수 있습니다..source. ./loadScripts.sh$PATH

그렇게 하는 것은 잘못된 것입니다 find... | while read...; do . ...; done. 우선 위에서 언급한 모든 이유 때문입니다.찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?, 또한 bash이 옵션이 활성화되지 않은 경우를 포함하여 여러 셸에서 루프가 하위 셸에서 실행되므로 소스 파일의 함수는 해당 하위 셸에서만 정의되기 때문입니다.lastpipewhile

버전 4.4 이상을 사용하고 싶지만 파일 목록을 정렬하고 숨겨진 파일을 포함하지 않도록 find주의하려면 다음을 수행할 수 있습니다.findbash

while IFS= read -rd '' -u3 script; do
  . "$script"
done 3< <(LC_ALL=C find scripts/ -mindepth 1 -maxdepth 1 -name '*.sh' -type f -print0)

여기에 추가하십시오 -type f(파일 유형을 제한하려면정기적인) 사용을 정당화하기 위해 find.

zsh대신 을 사용하는 경우 bash다음을 수행할 수 있습니다.

for script (scripts/*(ND.)) . $script

동등한 파일로( .일반 파일만 해당, D숨겨진 파일 포함)

또는:

for script (scripts/*(ND.)) emulate sh -c '. $script'

이러한 스크립트의 sh구문이 .sh확장 프로그램에서 제안한 대로인 경우.


posix¹ bash는 이 옵션의 활성화 여부와 관련하여 다르게 동작합니다.

관련 정보