“source x”와“의 차이점은 무엇입니까? Bash에서 x”와“./x”? bash 소스 가 있습니다. #!/bin/bash if [ $#

run.sh다음과 같이 하나의 bash 소스 가 있습니다.

#!/bin/bash
if [ $# -ne 1 ]; then
    exit
fi
...

두 가지 방법으로 실행하면 다른 동작이 있습니다. 첫 번째 방법은

source run.sh

실행 후 터미널을 닫습니다. 두 번째 방법은

./run.sh

이것은 단순히 스크립트 실행을 마치고 터미널에 남아 있습니다. bash 스크립트를 종료 source run.sh하고 ./run.sh실행 하는 명령이 있는지 묻습니다 . 나는 시도했지만 return제대로 ./run.sh실행 되지 않습니다 .

더 일반적으로, 나는 왜 이런 일이 일어나고 있는지, 그리고 “source”와 “.”를 사용하는 것의 차이점에 관심이 있습니다. 스크립트 실행?



답변

대답하기 전에 몇 가지 설명이 필요하다고 생각합니다. 다음 세 줄을 분석해 봅시다.

source run.sh
. run.sh
./run.sh

처음 두 줄은 정확히 동일합니다. .실제로에 대한 별칭입니다 source. 어떤 source일은하는, 현재의 상황에 따라서 전화를 쉘 스크립트를 실행하는 exit쉘을 종료합니다.

그러나 세 번째 줄 (혼란스러운 줄)은 다른 줄과 아무 관련이 없습니다. ./run.sh단지 경로이며, (예를 들어)와 동일 /home/user/run.sh하거나 /usr/bin/something. 셸의 명령은 공백으로 구분됩니다. 그래서,이 경우, 명령이 아니다 ., 그러나입니다 ./run.sh: 하위 쉘이 실행됩니다 것을이 수단과 그 exit바로 하위 쉘에 영향을 미칠 것입니다.


답변

세 가지 방법 :

스크립트를 함수로 묶고 return 만 사용할 수 있습니다.

#!/usr/bin/env bash
main() {
    ...
    return 1
    ...
}
main "$@"

대화식 쉘에서 스크립트를 제공하는지 테스트 할 수 있습니다.

if [[ $- = *i* ]]; then
    return 1
else
    exit 1
fi

돌아 가려고 할 수 있고 실패하면 종료하십시오.

return 1 2>/dev/null || exit 1

답변

‘include’문에서와 같이 ‘source’명령을 생각하십시오. 인수의 내용을 가져와 마치 마치 직접 실행 된 것처럼 실행합니다. 이 경우 명령은 ‘run.sh’인수와 함께 ‘source’이고 run.sh는 run.sh의 내용을 명령 줄에 입력 한 것처럼 정확하게 실행됩니다.

‘./run.sh’를 실행할 때 ‘./run.sh’가 명령이며 인수가 없습니다. 이 파일은 바이너리가 아닌 일반 텍스트이므로 쉘은 shebang에서 인터프리터 (첫 번째 줄의 ‘#!’)를 찾고 ‘/ bin / bash’를 찾습니다. 따라서 쉘은 bash의 새 인스턴스를 시작하고 run.sh의 내용이이 새 인스턴스 내에서 실행됩니다.

첫 번째 경우, bash가 ‘exit’명령에 도달하면 명령 행에 입력 한 것처럼 정확하게 실행됩니다. 두 번째 인스턴스에서는 쉘이 시작된 bash 프로세스에서 실행되므로이 ​​bash 인스턴스 만 ‘exit’명령을 수신합니다.

bash에 줄을 입력하면 첫 번째 공백 앞의 모든 것이 명령으로 처리되고 그 뒤에 오는 것은 인수로 처리됩니다. ‘.’명령 ‘source’의 별칭입니다. ‘를 실행할 때. run.sh ”. ‘ 공백으로 인수와 구분되므로 자체 명령입니다. ‘./run.sh’를 실행할 때 명령은 ‘./run.sh’및 ‘.’입니다. ‘.’와 함께 run.sh에 대한 상대 경로의 일부입니다. 현재 폴더를 나타냅니다.