bash 스크립트를 종료하지만 터미널을 종료하지 않는 방법


183

exit쉘 스크립트에서 명령을 사용 하면 스크립트가 터미널 (프롬프트)을 종료합니다. 스크립트를 종료 한 다음 터미널에 머무를 수있는 방법이 있습니까?

내 스크립트 run.sh는 직접 또는 다른 스크립트에서 제공함으로써 실행됩니다.

편집 : 더 구체적으로 두 스크립트 run2.sh가 있습니다

...
. run.sh
echo "place A"
...

run.sh같은

...
exit
...

나는하여 실행할 때 . run2.sh, 그리고 그것을 공격하는 경우 exit에 코드 라인을 run.sh, 나는 그것이 단자에 중지하고 거기에 있고 싶어. 그러나를 사용 exit하면 전체 터미널이 닫힙니다.

추신 : 사용하려고 return했지만 코드 라인 echo이 계속 실행됩니다 ....


5
나는 정말로 정말로 정말로 물어봐야한다 : 왜 소스 스크립트에서 exit를 사용 하는가?
Ignacio Vazquez-Abrams

3
exit 명령은 터미널 세션 / 로그인을 종료하지 않아야합니다. exit 0성공한 후 스크립트를 종료하는 데 사용 하는 경우 예를 들어 스크립트를 실행할 때 ./test.sh출력이 표시되지만 콘솔은 열린 상태로 유지됩니다.
벤 애쉬튼

shell실제로 쉘 터미널을 여는 명령을 사용할 수 있습니다 . 내 자신의 경험은 그러나 이것이 일어나지 않는다는 것입니다 exit. Exit는 보통 부모 스크립트에 제어권을줍니다.
Willem Van Onsem

답변:


258

"문제"는 실제로 스크립트를 소싱하고 실행하지 않는다는 것입니다. 파일을 소싱 할 때, 그 내용은 서브 쉘을 생성하는 대신 현재 쉘에서 실행됩니다. 따라서 종료를 포함하여 모든 것이 현재 쉘에 영향을 미칩니다.

을 사용하는 대신을 사용 exit하려고합니다 return.


2
도움이 된 다른 설명은 다음과 같습니다. askubuntu.com/a/53179/148337
3cheesewheel

맞지만 이것은 좋은 대답이 아닙니다. 호출 스크립트가 호출 한 스크립트가 액세스해야하는 변수 나 함수를 선언 할 수 있음을 무시합니다. 리턴 코드를 설정하고 runs.sh@ruakh 에서 처리하는 방법을 설명하는 것이 좋습니다.이 질문에 대한 답변이 더 좋습니다.
MikeSchinkel

5
함수가 중첩 된 호출 인 경우 어떻게합니까? 즉, a는 b를 호출하고, b는 c를 호출하고, c는 a와 b를 즉시 종료하려고합니다.
Michael

소스는 복사 붙여 넣기와 거의 동일합니다. 그것은 사용하는 것이 좋습니다 sh <script>또는 bash <script>하나의 스크립트를 실행하고 어떤 시점에서 종료하고자하는 경우
peterchaula

42

예; return대신 사용할 수 있습니다 exit. 주요 목적은 쉘 함수에서 리턴하는 것이지만 source-d 스크립트 내에서 사용하면 해당 스크립트에서 리턴됩니다.

으로 의 §4.1 "Bourne 쉘 내장 명령" 강타 참조 설명서 풋 그것은 :

     return [n]

쉘 함수가 리턴 값 n 으로 종료되도록합니다 . 경우 N이 공급되지 않으며, 반환 값은 함수에서 실행 된 마지막 명령의 종료 상태입니다. 이도에 실행되는 스크립트의 실행을 종료하기 위해 사용될 수있다 .(또는 source하나 반환) 내장 해당 스크립트의 종료 상태와 스크립트에서 실행 된 마지막 명령의 종료 상태 또는. RETURN트랩 과 관련된 모든 명령 은 기능 또는 스크립트 이후 실행이 재개되기 전에 실행됩니다. 또는 return로 스크립트 실행 중에가 아닌 함수 외부에서 사용되는 경우 반환 상태는 0 이 아닙니다 ..source


3
return함수에서만 사용할 수 있습니다. 당신이 사용하는 경우 return와 쉘 스크립트 (예 :로 실행 sh run.sh-), bash는 오류보고 return: can only 기능에서 복귀 '또는 공급 script`
Tzunghsing 데이비드 웡

@ TzungsingDavidWong :이 답변의 대부분은 공식 참조 매뉴얼의 인용이라는 것을 알고 있습니까? 그리고 당신이 인용 한 오류 메시지는 귀하의 주장 대신이 답변에 동의합니까?
ruakh

난 당신에게 동의하지 않습니다. return스크립트가 쉘 스크립트로 실행되고에 의해 실행되지 않으면 작동하지 않는다는 것을 지적하고 싶습니다 . (또는 source). BTW, 어디서 찾을 수 source -d있습니까?
Tzunghsing David Wong

9

을 사용하여 스크립트를 실행하는 대신 또는 . run2.sh을 사용하여 스크립트를 실행할 수 있습니다sh run2.shbash run2.sh

새로운 하위 셸이 시작되고 스크립트를 실행 한 다음 스크립트 끝에서 닫히고 다른 셸은 열린 상태로 유지됩니다.


그렇다면 왜 두 번째 매개 변수 sh "." run2.sh입니까?
CHAN

@ H0WARD 당신이 맞습니다. 점을 제거하는 것을 잊었습니다. 지금 답변을 편집했습니다.
Viorel Mirea

1
OP는 명시 적으로 소스를 요구 사항으로 명시합니다.
Jonathan Neufeld

4

return 문 / 명령 뒤에 여분의 exit 명령을 추가하여 명령 줄에서 스크립트를 실행하고 터미널에서 소싱 할 수 있습니다.

스크립트의 예제 종료 코드 :

   if [ $# -lt 2 ]; then
     echo "Needs at least two arguments"
     return 1 2>/dev/null
     exit 1
   fi

exit명령 뒤에 스크립트를 소싱 할 때 명령이 있는 행은 호출되지 않습니다 return.

스크립트를 실행할 때 return명령에 오류가 발생합니다. 따라서 오류 메시지를로 전달하여 표시하지 않도록합니다 /dev/null.


3

실제로, 나는 당신이 어떻게 뭉치 게되는지 혼란스러워 할 것이라고 생각합니다 run a script.

내장 스크립트가로 끝나더라도 sh스크립트를 실행하는 데 사용 하는 sh ./run2.sh경우 exit터미널 창이 계속 유지됩니다.

당신이 사용하는 경우 .또는 source, 터미널 창 가까이뿐만 아니라 / 첨자 끝을 종료합니다.

자세한 내용 은 사용 ? 의 차이점은 무엇입니까? 를 참조하십시오 .shsource


2

이것은 run2.sh 스크립트 안에 run 함수를 넣는 것과 같습니다. bash tty에서 run2.sh 파일을 소싱하는 동안 실행 내부 종료 코드를 사용합니다. 실행 기능에 스크립트를 종료 할 수있는 전원을 제공하고 run2.sh에 종료자를 종료 할 수있는 전원을 제공하십시오. 그런 다음 실행 기능에는 테미 네이터를 종료하는 전원이 있습니다.

    #! /bin/sh
    # use . run2.sh

    run()
    {
        echo "this is run"
        #return 0
        exit 0
    }

    echo "this is begin"
    run
    echo "this is end"

어쨌든, 나는 Kaz와 함께 디자인 문제라고 승인합니다.


이 답변이 무엇을하려고하는지 텍스트에서 명확하지 않지만, 당면한 문제를 해결하지는 못합니다.
Luís de Sousa

2

나는 똑같은 문제를 겪었고 위의 대답과 궁극적으로 나를 위해 일한 것이 무엇인지 이해했다.

  1. 예를 들어, 의도 된 스크립트를 호출하는 shebang 행이 있어야합니다.

    #!/bin/bashbash스크립트를 실행하는 데 사용

나는 두 종류의 shebang을 가진 대본을 가지고 있습니다. 이 때문에, 사용 sh또는 것은 .그것이 잘못된 실행으로 이어질로, 믿을 수 없었다 (같은 때 불완전하게 실행하는 데 밖으로 스크립트 보석금)

그러므로 그 대답은

    • 스크립트에 shebang이 있는지 확인하여 의도 한 핸들러에 대해 의심의 여지가 없도록하십시오.
    • .sh 파일을 chmod하여 실행할 수 있도록합니다. (chmod +x file.sh)
    • sh또는 없이 직접 호출.

      (./myscript.sh)

이것이 비슷한 질문이나 문제가있는 사람에게 도움이되기를 바랍니다.


1

점이있는 소스 모드에서 실행하기 때문에 이것이 발생한다고 생각합니다.

. myscript.sh

서브 쉘에서이를 실행해야합니다.

/full/path/to/script/myscript.sh

'source'http: //ss64.com/bash/source.html


. myscript.sh작동 하면 스크립트의 전체 경로가 필요하지 않습니다 . 기껏해야합니다 ./myscript.sh.
Álvaro González

1

다른 스크립트에서 언급했듯이 소스 스크립트와 실행 스크립트는 returnvs. exit를 사용 하여 동일한 세션을 열어 두는 것이 맞습니다 .

소스의 유무에 관계없이 세션을 열어 두어야하는 스크립트를 원한다면 관련 팁이 있습니다.

다음 예제는 / foo.sh처럼 직접 또는 소스 로 실행할 수 있습니다 . 어느 쪽이든 "종료"후에 세션이 열린 상태로 유지됩니다. 문자열은 함수가 외부 스크립트의 인수에 액세스 할 수 있도록 전달됩니다.. foo.shsource foo.sh$@

#!/bin/sh
foo(){
    read -p "Would you like to XYZ? (Y/N): " response;
    [ $response != 'y' ] && return 1;
    echo "XYZ complete (args $@).";
    return 0;
    echo "This line will never execute.";
}
foo "$@";

터미널 결과 :

$ foo.sh
$ XYZ를 원하십니까? (Y / N) : n
$입니다. foo.sh
$ XYZ를 원하십니까? (Y / N) : n
$ |
(터미널 창은 열려 있고 추가 입력을 받아들입니다)

이 기능은 단일 터미널에서 스크립트 변경 사항을 빠르게 테스트 하면서 작업하는 동안 메인 exit/ 아래에 많은 스크랩 코드를 유지하는 데 유용 return합니다. (당신이 또는 다른 방법으로 호출 할 수 없습니다 수 있습니다 스크립트의 톤이있는 경우)가 훨씬 덜 투박한 단지 사용에 비록 그것은 또한 의미에서 코드를 더 휴대용 만들 수 returnexit적절한 경우.


0

터미널 에뮬레이터에없는 경우 -hold소스 스크립트를 삭제하고 다음을 사용하여 터미널을 유지할 수 있습니다.

#!/bin/sh
sed "s/exit/return/g" script >/tmp/script
. /tmp/script
read

그렇지 않으면 당신은 사용할 수 있습니다 $TERM -hold -e script


0

또한 예상 반환 값으로 반환하십시오. 그렇지 않으면 exit가 발생할 때 exit를 사용하면 소스가 다른 프로세스 (인스턴스)를 작성하지 않으므로 기본 쉘에서 종료됩니다.


0

하나 쉘 스크립트로 실행하거나 rc 파일로 공급 될 안전 스크립트를 작성하려면 스크립트를 확인하고 비교할 수 $0$BASH_SOURCE및 여부를 결정 exit안전하게 사용할 수 있습니다.

여기에 대한 짧은 코드 스 니펫이 있습니다.

[ "X$(basename $0)" = "X$(basename $BASH_SOURCE)" ] && \
    echo "***** executing $name_src as a shell script *****" || \
    echo "..... sourcing $name_src ....."

-1

1) 엑시트 0이 성공하면 스크립트에서 나옵니다.

2) 엑시트 1이 실패하면 스크립트에서 나옵니다.

ur req에 따라 위의 두 가지를 시도 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.