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에 대한 상대 경로의 일부입니다. 현재 폴더를 나타냅니다.