Bash 함수에서 리턴과 종료의 차이점


429

종료 코드와 관련하여 Bash 함수에서 returnexit명령문 의 차이점은 무엇입니까 ?


55
팁 : help <command>쉘 내장 기능에 대한 정보를 얻으려면 쉘을 입력 하십시오. 귀하의 경우 help returnhelp exit
SiegeX

답변:


318

에서 man bashreturn [n];

함수가 실행을 중지하고 n으로 지정된 값을 호출자에게 반환합니다. n이 생략되면 리턴 상태는 함수 본문에서 마지막으로 실행 된 명령의 상태입니다.

...에 exit [n]:

쉘을 n 상태로 종료하십시오. n을 생략하면 종료 상태는 마지막으로 실행 된 명령의 종료 상태입니다. EXIT의 트랩은 쉘이 종료되기 전에 실행됩니다.

편집하다:

종료 코드와 관련하여 질문을 편집 한 결과 종료 코드와 관련 return이 없습니다. 종료 코드는 기능이 아닌 응용 프로그램 / 스크립트를 위한 것입니다 . 따라서 이와 관련하여 스크립트의 종료 코드를 설정하는 유일한 키워드 ( $?셸 변수를 사용하여 호출 프로그램이 포착 할 수있는 키워드 )는 exit입니다.

편집 2 :

마지막으로 언급 한 내용 exit은 몇 가지 의견을 제시합니다. 그것은 차별화하기로 결정했습니다 returnexit영업 이익의 이해, 그리고 사실에서 어떤 프로그램 / 쉘 스크립트의 특정 시점,exit 호출 프로세스 종료 코드와 스크립트를 종료하는 유일한 방법입니다.

그것은 설정 : 쉘에서 실행되는 모든 명령은 로컬 "종료 코드"를 생산하고 $?그 코드에 변수와 함께 사용할 수 있습니다 if, &&및 조건에 다른 사업자가 다른 명령을 실행합니다.

이 종료 코드 (및 $?변수 값 )는 각 명령 실행에 의해 재설정됩니다.

또한, 스크립트에 의해 실행 된 마지막 명령의 종료 코드는 호출 프로세스에서 볼 수 있듯이 스크립트 자체의 종료 코드로 사용됩니다.

마지막으로 함수는 호출 될 때 종료 코드와 관련하여 쉘 명령으로 작동합니다. 함수의 종료 코드 (함수 )는를 사용하여 설정됩니다 return. 따라서 return 0함수에서 실행될 때 함수 실행이 종료되고 종료 코드는 0입니다.


10
정확히. 항상 현재 쉘에서 값을 반환합니다. 함수 내부에 있는지 여부는 중요하지 않습니다.
Diego Sevilla

10
편집에 대한 의견 : 반환 값과 종료 코드를 혼동 할 수 있지만 func(){ return 50; };func;echo $?50을 에코합니다. 따라서 $?쉘 변수는로 제한되지 않는 것 같습니다 exit.
lecodesportif

8
" $?가장 최근에 실행 된 포 그라운드 파이프 라인의 종료 상태로 확장됩니다." 이 엑시트는 쉘에서 호출 exit(또는 스크립트의 끝을 누르는 형태) 또는 return함수 내의 호출 형태 일 수 있습니다.
SiegeX

11
@lecodesportif : $? 현재 프로세스 / 스크립트exit 중이 스크립트 가 실행 한 마지막 명령의 결과로 제한됩니다 . 마지막 스크립트 행은 그 함수를 호출이며, 경우에 따라서, 그 함수가 반환 (50)는, 예,은 $?당신이 생산하고 있음을 당신이라는 프로세스에 로 할 필요가 없다 그러나 50입니다, return이이며, 때문에 현재 스크립트로 제한됩니다. 이 함수 호출이 스크립트의 마지막 문장 인 경우에만 리턴됩니다. exit그러나 항상 스크립트를 완료 $? 하고 호출 프로세스에 대해 해당 값을 리턴 하십시오 .
Diego Sevilla

11
-1 " return나가 종료 코드와 관련이 없습니다." 실험은 함수의 리턴 코드와 스크립트의 종료 코드 사이에 기능적 차이가 없음을 알려줍니다.
Jack

296

return현재 함수가 범위를 벗어나는 반면 exit스크립트는 호출 된 지점에서 종료됩니다. 다음은이를 설명하는 데 도움이되는 샘플 프로그램입니다.

#!/bin/bash

retfunc()
{
    echo "this is retfunc()"
    return 1
}

exitfunc()
{
    echo "this is exitfunc()"
    exit 1
}

retfunc
echo "We are still here"
exitfunc
echo "We will never see this"

산출

$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()

17
좋은 예입니다. 종료 값 1을 1로 표시 할 수도 있습니다 $?.
Diego Sevilla

48
"retfunc"를 호출하기 전에 "set -e"를 추가하면이 함수는 "여전히 여기에 있습니다"를 인쇄하지 않습니다.
Michael

4
그러나 echo fnord | while read x; do exitfunc; done; echo "still here""여전히 여기"가 인쇄됩니다. while이 시나리오 에서는 하위 셸만 종료 된 것으로 보입니다 .
tripleee

대략적인 해결 방법은 done || exit $?있지만 추악하고 정확하게 동일하지는 않습니다.
tripleee

2
+1 다음을 추가하는 것이 유용 할 수 있습니다 :``` return는 현재 함수 나 소스 스크립트가 범위 를 벗어납니다. ''`` .
Isaac

56

나는 두 사람이 어떻게 사용되는지 설명하지 않기 때문에 누군가가 질문에 완전히 대답했다고 생각하지 않습니다. 알겠습니다. exit는 스크립트가 호출되는 모든 위치에서 스크립트를 종료하고 종료 또는 종료 0 또는 종료 7과 같은 상태를 스크립트에 할당 할 수 있다는 것을 알고 있습니다. 다른 스크립트 등에 의해 호출 된 경우 스크립트가 강제로 중지 된 방법을 판별하는 데 사용할 수 있습니다. 종료시 충분합니다.

호출시 return은 함수의 동작을 나타내도록 지정된 값 (일반적으로 1 또는 0)을 반환합니다. 예를 들면 다음과 같습니다.

    #!/bin/bash
    isdirectory() {
      if [ -d "$1" ]
      then
        return 0
      else
        return 1
      fi
    echo "you will not see anything after the return like this text"
    }

다음과 같이 확인하십시오.

    if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi

또는 이와 같이 :

    isdirectory || echo "not a directory"

이 예제에서는 테스트를 사용하여 디렉토리를 찾았는지 여부를 표시 할 수 있습니다. 리턴 후에는 함수에서 실행되지 않습니다. 쉘에서 0은 true이지만 다른 prog lang과는 달리 false는 1입니다.

함수에 대한 자세한 정보 : http://www.linuxjournal.com/content/return-values-bash-functions

참고 : isdirectory 기능은 설명을위한 것입니다. 실제 스크립트에서 이러한 옵션을 수행하는 방법이 아닙니다.


3
또는 test -d $1동일한 결과를 얻기 위해 사용 하십시오. 하지 마십시오 if <check> return else return. <check>적어도 내가 아는 모든 언어에서 같은 일을 할 것입니다.
erikbwork

4
erik의 말에 대해 더 명확 isdirectory() { [ -d "$1" ]; }하게 말하면 : 여기있는 것과 정확히 동일하게 작동합니다 : 코드의 끝에 도달하거나 return인수가없는 것으로 쉘 함수의 기본 반환 값은 가장 최근의 명령.
Charles Duffy

11
다른 주석가들은 Mike Q의 사례 스타일을 비판하고 있는데, 실제로 return진술 의 행동에 대해 이야기하고있을 때 입니다. 그의 예는 단순하고 생산에 사용되지 않는 것이 사실입니다. 그러나 그것은 간단하기 때문에 그의 임무를 잘 수행합니다. 아무 문제가 없습니다.
Mike S

고마워 Mike S, 네, 가장 간단한 예제가 exit vs return을 가장 잘 설명한다는 데 동의합니다. 다른 의견은 확실히 유효하며 고급 bash 코더를 위해 고려해야합니다 ;-)
Mike Q

1
어떤 사람들은 그것이 질문과 정확히 관련이 없다고 말할 수도 있지만 , 내가이 질문을 찾게 만든 문제와 관련되어 답변했습니다. :-)
Jesse Steele

33

함수는 스크립트 내부에 있으며 일반적으로 return 문을 사용하여 호출 한 시점에서 반환합니다. 외부 스크립트를 호출하는 것은 완전히 다른 문제이며 스크립트는 일반적으로 exit 문으로 종료됩니다.

"종료 코드와 관련하여 BASH 함수의 return 및 exit 문 간의 차이"는 거의 없습니다. 둘 다 자체가 아닌 상태를 반환합니다 . 상태 0은 성공을 나타내고 다른 상태 (1-255)는 실패를 나타냅니다. return 문은 스크립트가 호출 된 곳에서 스크립트로 돌아가고 exit 문은 스크립트가있는 곳에서 전체 스크립트를 종료합니다.

return 0  # returns to where the function was called.  $? contains 0 (success).

return 1  # returns to where the function was called.  $? contains 1 (failure).

exit 0  # exits the script completely.  $? contains 0 (success).

exit 1  # exits the script completely.  $? contains 1 (failure).

함수가 단순히 return 문없이 끝나는 경우 마지막으로 실행 된 명령의 상태가 상태 코드로 반환되며 $? ).

return and exit는 0에서 255 사이의 상태 코드를 반환합니다. $? 합니다. 상태 코드에 다른 것을 넣을 수 없습니다 (예 : "cat"반환). 이거 작동 안 할거야. 그러나 스크립트는 상태 코드를 사용하여 실패에 대한 255 가지 다른 이유를 전달할 수 있습니다.

호출 스크립트에 포함 된 변수를 설정하거나 함수에서 결과를 반향하고 호출 스크립트에서 명령 대체를 사용할 수 있습니다. 그러나 리턴 및 종료의 목적은 C와 같은 프로그래밍 언어에서 예상되는 값 또는 계산 결과가 아닌 상태 코드를 전달하는 것입니다.


25

때때로, 당신은 사용하여 스크립트를 실행 .하거나 source.

. a.sh

당신이 포함하는 경우 exit의를 a.sh, 그냥 스크립트를 종료하지만, 쉘 세션을 종료하지 않습니다.

당신이 포함 된 경우 return에서 a.sh, 단순히 스크립트 처리를 중지합니다.


1
그러나 방금 a.sh를 실행하면 error가 발생 return: can only 'return' from a function or sourced script하여 일반 스크립트에 적합하지 않습니다.
피터-복원 모니카

스크립트의 최상위 수준에서는 all상황에 적합하지 않습니다 . 서브 쉘을 생성하지 않고 현재 쉘에서 스크립트를 사용 .하거나 source실행합니다. 스크립트는 어떻게 사용되는지 알아야 합니다. 그것을 반대하는 사용자에게 화가 있습니다. 개인적으로 스크립트를 처음 실행하기 전에 읽는 것이 좋습니다.
Jesse Chisholm

3
내가 겪은 놀라운 속임수는 trap함수 를 사용한 ERR EXIT다음 실패한 명령의 종료 코드를 저장 errCode=$?한 다음 "소스가 없어서 반환 할 수없는 경우" return $errCode || exit $errCode라는 ||의미로 스크립트를 종료합니다 (소싱 여부) 대신 종료하십시오. "
dragon788

6

간단한 말로 (주로 코딩의 초보자를 위해), 우리는 말할 수 있습니다.

`return` : exits the function,
`exit()` : exits the program(called as process while running)

또한 당신이 관찰한다면, 이것은 매우 기본이지만 ...

`return` : is the keyword
`exit()` : is the function

1
bash 스크립트에서 exit보다 크거나 적은 함수 return입니다. 내장 명령입니다. 그들은 심지어 예약어가 아닙니다.
피터-복원 모니카

6
  • exit현재 프로세스를 종료 ; 종료 코드 유무에 관계없이이를 프로그램 기능 이상의 시스템으로 간주하십시오. 소싱 할 때 exit셸이 종료되지만 실행하면 exit스크립트 만 종료 됩니다.

  • return함수에서 호출 후 리턴 코드 유무에 관계없이 명령으로 돌아갑니다. return선택 사항이며 함수 끝에서 암시 적입니다. return함수 안에서만 사용할 수 있습니다.

소스를 제공하는 동안 exit쉘을 죽이지 않고 함수 내에서 스크립트를 사용하는 것은 쉽지 않습니다 . 예를 들어 '테스트'스크립트에서 더 낫습니다.

#!/bin/bash
function die(){
   echo ${1:=Something terrible wrong happen}
   #... clean your trash
   exit 1
}

[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"

다음을 수행

user$ ./test
Whatever is not available
user$

test 쉘이 닫힙니다.

user$ . ./test
Whatever is not available

test 완료되고 메시지가 표시됩니다.

상기 용액의 잠재적 절차를 둘러싸이고 ()

#!/bin/bash
function die(){
   echo $(1:=Something terrible wrong happen)
   #... clean your trash
   exit 1
}

( # added        
    [ -f /whatever/ ] || die "whatever is not available"
    # now we can proceed
    echo "continue"
) # added

이제 두 경우 모두 test종료됩니다.


()블록을 추가하면 하위 쉘에 해당 블록을 넣고 ., 테스트 스크립트를 정상적으로 실행 한 것처럼 (소스) 명령을 효과적으로 수행 할 수 있습니다. 스크립트가 실행되지 IOF .또는 source당신은 효과적으로 2 서브 쉘이있다.
Jesse Chisholm

3

OP의 질문 : 종료 코드와 관련하여 BASH 함수의 return 문과 exit 문의 차이점은 무엇입니까?

분명히 몇 가지 설명이 필요합니다.

  • (쉘)의 실행을 종료하기 위해 (종료) 문은 필요하지 않다. (반환) 문이 없어도 코드 목록의 끝에 도달하면 (함수)가 종료됩니다.
  • (종료) 명세서는 종료 된 (쉘)로부터 값을 되돌려 보낼 필요가 없다. 모든 프로세스는 내장 변수 $? 항상 숫자 값이 있습니다. "? = 1"처럼 설정할 수없는 특수 변수이지만 특수한 방식으로 만 설정됩니다 (아래 * 참조). $의 가치? (function | sub shell이라고 함)에서 마지막으로 실행될 명령은 (function caller | parent shell)로 다시 전달되는 값입니다. 마지막으로 실행 된 명령이 ( "return [n]"| "exit [n]") 또는 일반 ( "return") 또는 호출 된 함수 코드에서 마지막 명령이되는 다른 것이 사실입니다.

위의 글 머리표 목록에서 항상 첫 번째 항목 또는 두 번째 항목 중 "(x | y)"중에서 선택하여 함수 및 리턴 또는 쉘 및 종료에 대한 명령문을 각각 가져 오십시오.

그들 모두 특수 변수 $의 일반적인 사용법을 공유한다는 것이 분명합니까? 종료 후 값을 위쪽으로 전달합니다.

* 이제 특별한 방법은 $? 설정할 수 있습니다 :

  • 호출 된 함수가 종료되고 호출자에게 반환되면 $? 발신자의 최종 가치는 $? 종료 된 기능에서.
  • 상위 쉘이 단일 서브 쉘을 내재적으로 또는 명시 적으로 대기하고 해당 서브 쉘이 종료되어 해제되면 $? 부모 셸에서 $의 최종 값과 동일합니까? 종료 된 서브 쉘에서.
  • 일부 내장 함수는 $를 수정할 수 있습니까? 그들의 결과에 따라. 그러나 일부는 그렇지 않습니다.
  • 내장 함수 "return"및 "exit", 숫자 인수 뒤에 $? 인수와 함께 실행을 종료합니다.

그 $에 주목할 가치가 있습니까? 다음과 같이 하위 쉘에서 exit를 호출하여 값을 지정할 수 있습니다.

# (exit 259)
# echo $?
3  

4
일부가 누락 된 경우 최종 종료 값이 단일 바이트이므로 exit 259에코됩니다 3. 259 % 256 = 3
Jesse Chisholm

0

우선 return, 키워드이고 exit내 친구는 기능입니다.

즉, 여기에 가장 간단한 설명이 있습니다.

return 함수에서 값을 반환합니다.

exit 현재 쉘을 종료하거나 버립니다.


실제로는 아닙니다! 당신은 논리적으로 잘못되었습니다. 종료는 return키워드 인 동안 함수 입니다. 리턴은 단순한 종료 코드 그 이상의 것이므로 비교가 불공평합니다.
Ahmad Awais 2012 년

나는 내가 만들려고하는 요점을 더 명확하게하기 위해 그것을 편집했습니다. 도와 주셔서 감사합니다.
Ahmad Awais

4
"키워드" 도 exit아니고 return, bash 매뉴얼에서 "예약어"라고 부르기도합니다. bash 함수의 의미에서 "함수"도 아닙니다. 둘 다 bash lingo의 내장 명령 입니다. (이 있다 라는 C 표준 라이브러리 함수 exit()와 C 프로그래밍 언어는 예약어를 가지고 return있지만, 그는 자신의 의미 호기심과 유사하다하더라도, bash는 명령과 혼동해서는 안된다.)
피터 - 분석 재개 모니카
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.