bash 함수의 암시 적 반환?

다음과 같은 bash 함수가 있다고 가정 해 보겠습니다.

gmx(){ echo "foo"; } 

이 함수는 암시 적으로 echo 명령의 종료 값을 반환하거나 반환이 필요합니까?

gmx(){ echo "foo"; return $? } 

bash가 작동하면 bash 함수의 최종 명령의 종료 상태는 “반환”되지만 100 % 확실하지는 않습니다.

Answer

return는 쉘 함수 또는”점 스크립트 “(소스 스크립트)에서 명시 적 반환을 수행합니다. return가 실행되지 않으면 셸 함수 또는 도트 스크립트의 끝에서 암시 적으로 반환됩니다.

return는 매개 변수없이 실행되며 가장 최근에 실행 된 명령의 종료 상태를 반환하는 것과 동일합니다.

이것이 모든 POSIX에서 return가 작동하는 방식입니다. 쉘.

예 :

gmx () { echo "foo" return "$?" } 

따라서

gmx () { echo "foo" return } 

같음

gmx () { echo "foo" } 

일반적으로 $? 전혀. 예를 들어 값을 여러 번 조사해야하는 경우와 같이 나중에 사용하기 위해 저장해야하는 경우에만 실제로 필요합니다 (이 경우 값을 변수에 할당하고 해당 변수에 대해 일련의 테스트를 수행합니다).

댓글

  • return 사용의 한 가지 단점은 , 하위 셸과 동일한 프로세스에서 cmd를 실행하는 일부 셸이 수행하는 최적화를 방지합니다. 많은 셸에서 이는 또한 함수의 종료 상태가 ' cmd가 종료되었을 때 종료되었다는 정보를 전달하지 않음을 의미합니다. (대부분의 셸은 ' 어쨌든 해당 정보를 검색 할 수 없습니다.)
  • pdksh 및 일부 파생물 (예 : OpenBSD sh 또는 posh), '는 return -- "$?"가 필요합니다. 마지막 명령이 음수를 반환 한 함수일 가능성이 있습니다. mksh (pdksh 기반도 있음)는 함수가 음수 값을 반환하는 것을 금지합니다.
  • 이것이 도움이 되었으니 감사합니다. ' return xexit x와 어떻게 다르게 작동하는지 이해하지 못합니다. 내가 아는 유일한 것은 현재 프로세스를 종료하지 않습니다.
  • @AlexanderMills 글쎄요. ' 제가 말한 내용은 다음과 같습니다. return는 함수 또는 도트 스크립트에서 반환하는 데 사용됩니다. exit는 완전히 다른 작업을 수행합니다 (프로세스 종료).
  • 맞습니다.이 문제를 더 잘 처리하기 시작한 것 같습니다.

답변

bash(1) 매뉴얼 페이지에서 :

실행시 함수의 종료 상태는 본문에서 실행 된 마지막 명령의 종료 상태입니다.

댓글

  • 맞습니다. 결과적으로 return 문이 종료 상태에 지나지 않을 수도 있습니다.
  • return는 내장 명령입니다. return 1exit 1 등과는 다릅니다.
  • " return [n] : 함수가 실행을 중지하고 n으로 지정된 값을 호출자에게 반환합니다. n이 생략되면 반환 상태는 함수 본문에서 실행 된 마지막 명령의 상태입니다. " (ibid) 따라서 return 지정된 경우 함수의 종료 상태를 특정 값으로 강제합니다.
  • @AlexandwrMills 예, returnexit는 둘 다 내장되어 있지만 return는 함수 내에서만 사용할 수 있습니다. ' return로 스크립트를 종료 할 수 없습니다. 종료 상태는 명령이 반환하는 값입니다. return는 해당 값을 반환하는 명령입니다. 따라서 " return 문은 종료 상태 일뿐입니다 "는 정확하지 않습니다. 하나는 값이고 다른 하나는 명령에 값을 더한 것입니다.
  • @AlexanderMills, return 함수에서 반환, exit는 전체 셸을 종료합니다. ' in과 정확히 동일합니다. 예를 들어 C와 returnexit(n), 또는 Python에서 returnsys.exit().

답변

이미 제공된 답변에 몇 가지주의 사항을 추가하겠습니다.

  • return는 구문의 관점에서 보면 쉘에 매우 특별한 의미를 가지고 있지만 쉘 내장 명령과 return 문입니다. 다른 간단한 명령처럼 구문 분석됩니다. 즉, 다른 명령의 인수에서와 같이 따옴표가없는 경우 $?는 split + glob의 적용을받습니다.

    따라서이를 방지하려면 $?를 인용해야합니다.

    return "$?" 
  • return는 일반적으로 어떤 옵션도 허용하지 않습니다 (ksh93 “는 일반적인 --help, --man, --author …). 예상되는 유일한 인수 (선택 사항)는 반환 코드입니다. 허용되는 반환 코드의 범위는 다양합니다. 쉘에서 쉘로, 0..255 외부의 값이

도 셸마다 다릅니다. 자세한 내용은 프로세스가 종료 될 때 기본 종료 코드 를 참조하세요.

대부분의 셸은 음수를 허용합니다 (결국 인수는 _exit() / exitgroup() 시스템 호출은 int이므로 최소한- 2 31 ~ 2 31 -1이므로 셸이 기능에 대해 동일한 범위를 허용하는 것이 합리적입니다.

대부분의 셸은 waitpid() 및 co. 해당 종료 상태를 검색하는 API이지만이 경우 $? 저장 할 때 0에서 255 사이의 숫자로 잘립니다. 함수를 호출하더라도 프로세스 생성을 포함하지 않고 waitpid()를 사용하여 모두 동일한 프로세스에서 수행되므로 종료 상태를 검색합니다. 많은 셸도 waitpid() 함수를 호출 할 때의 동작입니다. 즉, 음수 값으로 return를 호출하더라도 $?에는 양수가 포함됩니다.

p>

이제 return가 음수 (ksh88, ksh93, bash, zsh, pdksh 및 mksh, yash 이외의 파생물)를 허용하는 쉘 중에서 몇 가지 ( pdksh 및 yash)이 필요하며 return -- -123로 작성해야합니다. 그렇지 않으면 -123는 3 개의 -1, -2, -3 잘못된 옵션입니다.

pdksh 및 그 de 파생어 (예 : OpenBSD sh 또는 posh)는 $?에서 음수를 유지합니다. 즉, $?에 음수가 포함되어 있으면 return "$?" 작업이 실패합니다 (마지막 실행 명령이 음수를 반환 한 함수일 때 발생 함). ).

그러므로 return -- "$?"는 이러한 셸에서 더 좋습니다. 그러나 대부분의 셸에서 지원되지만 해당 구문은 POSIX가 아니며 실제로는 mksh 및 ash 파생물에서 지원되지 않습니다.

요약하면 다음과 같습니다. pdksh 기반 셸에서는 함수에 대한 인수에 음수를 사용할 수 있지만 그렇게하면 return "$@"가 작동하지 않습니다. 다른 셸에서는 return "$@"가 작동하므로 return에 대한 인수로 음수 (또는 0..255 이외의 숫자)를 사용하지 않아야합니다.

  • 내가 아는 모든 셸에서 함수 내에서 실행중인 하위 셸 내부에서 return를 호출하면 하위 셸이 종료됩니다 (있는 경우 제공된 종료 상태 또는 마지막 명령의 종료 상태 사용). 실행), 그러나 그렇지 않으면 함수에서 반환되지 않습니다 (저에게 POSIX가 보증을 제공하는지 여부는 확실하지 않습니다. 일부는 종료 서브 쉘 대신 exit를 사용해야한다고 주장합니다. 내부 기능). 예를 들어

    f() { (return 3) echo "still inside f. Exit status: $?" } f echo "f exit status: $?" 

    출력 :

    still inside f. Exit status: 3 f exit status: 0 
  • Answer

    예, 함수의 암시 적 반환 값은 마지막으로 실행 된 의 종료 상태입니다. 명령. 모든 쉘 스크립트의 어느 지점에서도 마찬가지입니다. 스크립트 실행 시퀀스의 어느 시점에서든 현재 종료 상태는 마지막으로 실행 된 명령의 종료 상태입니다. 변수 할당의 일부로 실행 된 명령도 : var=$(exit 34). 함수와의 차이점은 함수가 함수 실행이 끝날 때 종료 상태를 변경할 수 있다는 것입니다.

    “현재 종료 상태”를 변경하는 다른 방법은 하위 셸을 시작하고 다음으로 종료하는 것입니다. 필요한 모든 종료 상태 :

    $ $(exit 34) $ echo "$?" 34 

    예, 종료 상태 확장 는 인용해야합니다.

    $ IFS="123" $ $(exit 34) $ echo $? 4 

    (exit 34)도 작동합니다.
    어떤 사람들은 더 강력한 구조가 $(return 34)이고 종료가 실행중인 스크립트를 “종료”해야한다고 주장 할 수 있습니다. 그러나 $(return 34) 모든 버전의 bash에서 작동하지 않습니다. 따라서 이식 할 수 없습니다.

    종료 상태를 설정하는 가장 안전한 방법은 함수에서 작동, 정의 및 return하도록 설계된대로 사용하는 것입니다. :

    exitstatus(){ return "${1:-"$?"}"; } 

    그래서, 함수의 끝입니다. 아무것도 없거나 return 또는 return "$?"가있는 것과 정확히 동일합니다. 함수의 끝이 “함수의 마지막 코드 줄”을 의미 할 필요는 없습니다.

    #!/bin/sh exitstatus(){ a="${1:-"$?"}"; return "$a"; } gmx(){ if [ "$1" = "one" ]; then printf "foo "; exitstatus 78 return "$?" elif [ "$1" = "two" ]; then printf "baz "; exitstatus 89 return else printf "baz "; exitstatus 90 fi } 

    인쇄 :

    $ ./script foo 78 baz 89 baz 90 

    "$?"의 유일한 실제 용도는 해당 값을 인쇄하거나 echo "$?" 저장하는 것입니다. 변수에 포함 (임시 값이며 실행되는 모든 명령에 따라 변경됨) : exitstatus=$? (export EXITSTATUS="$?".

    return 명령에서 유효한 값 범위는 일반적으로 0 ~ 255이지만 126 + n는 일부 셸에서 특별한 종료 상태를 알리는 데 사용되므로 일반적인 권장 사항은 0-125를 사용하는 것입니다.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다