일반적으로 쉘 스크립팅과 특히 Bash에는 어떤 종료 모드가 있습니까?

일반적으로 쉘 스크립팅과 특히 Bash에는 어떤 종료 모드가 있습니까?

쉘 스크립트에서 "종료"는 일반적으로 자발적으로 또는 적어도 성공적으로 의미한다는 것을 알고 있습니다.종료세션(아니면 프로세스세션 내에서) 그리고 제가 아는 몇 가지 종료 모드가 있습니다.

1. 간단한 exit명령

첫 번째 셸 세션(shell-session 0)에 있는 경우 일반적으로 셸 CLI가 발생합니다.창문하지만 일부 하위 세션(예: 쉘 세션 1 이상)에 있는 경우 실행은 일반적으로 사용자를 이전 세션(예: 1 → 0)으로 다시 이동시킵니다.

exit SOME_EXIT-CODE2.명령

크게 3가지를 찾았어요종료 코드이 종료 유형의 경우:

  1. exit 0(성공).
  2. exit 1("0으로 나누기"와 같은 일반 오류 및 기타 작업은 허용되지 않습니다.)
  3. exit 2(Bash 4.xx에서와 같이 - 쉘 내장 함수의 남용, 예는 빈 함수입니다; myFunc() {}).

나는 종종 실행의 표시로 명령 시퀀스의 끝에 추가되는 것을 발견합니다.결과;가끔단위 테스트,좋다:

domain="$1" && test -z "$domain" && exit 2 
# Test if a user passes only one domain as a parameter, when executing this script

3. 스크립트를 추가하지 않고 종료

올바르게 기억한다면 Bash 스크립트 실행이 완료되면 해당 "끝"은 실제로 일반적인 *nix 용어로 "종료"입니다. 스크립트 자체는 사용자가 CLI 세션으로 다시 종료할 수 있는 세션입니다. 여기도 좀 있네종료 코드, 주어질 수 있습니다.

내 질문

일반적으로 쉘 스크립팅, 특히 Bash에 다른 "종료 모드"가 있습니까?

답변1

"탈퇴"는 일반적으로 자발적이거나 적어도 성공적인 종료를 의미합니다.

적어도 POSIX 텍스트는 사용하는 것 같습니다.출구외부 이유로 인해 프로세스가 종료되는 것이 아니라 자발적으로 프로세스를 종료하는 데에만 사용됩니다. (예를 들어wait()) 신호에 의해 종료된 프로세스는 성공한 것으로 간주되지 않으므로 성공적인 종료는 그런 의미에서 "종료"여야 합니다. 비록 이 용어들이 비공식적으로 덜 엄격하게 사용되었으면 좋겠지만.

일반적으로 쉘 스크립팅, 특히 Bash에 다른 "종료 모드"가 있습니까?

모델어떤 경우에는 (예를 들어 ) 특정 기술적 의미가 있지만 chmod()여기서는 생각할 수 없으므로 무엇을 요구하시는지 잘 모르겠습니다.

그럼에도 불구하고 쉘 스크립트는 최소한 다음과 같은 이유로 종료될 수 있습니다.

  1. 스크립트는 스크립트가 끝날 때까지 실행됩니다. 스크립트의 종료 상태는 마지막으로 실행된 명령의 종료 상태입니다.
  2. 스크립트가 실행됩니다.exit내장 명령논쟁의 여지가 없습니다. 마찬가지로 종료 상태는 마지막으로 실행된 명령의 상태입니다.
  3. 이 스크립트는 exit매개변수를 사용하여 명령을 실행합니다. 종료 상태는 매개변수의 값입니다.
  4. 스크립트가 설정되지 않은 변수를 참조합니다.set -u/set -o nounset시행 중입니다. 종료 상태는 쉘에 따라 다르지만 0은 아닙니다. (Bash는 그것을 사용하는 것 같습니다 127.) (*)
  5. 이 스크립트는 실패한 명령을 실행합니다.set -e/set -o errexit시행 중입니다. 종료 상태는 실패한 명령의 종료 상태입니다. (하지만 봐봐배쉬 FAQ 105질문에 대한 set -e. )
  6. 스크립트에 구문 오류가 발생했습니다. 쉘의 종료 상태는 0이 아닙니다. (Bash는 그것을 사용하는 것 같습니다 1.) (*)
  7. 스크립트 수신됨신호이로 인해 종료됩니다. 모든 신호가 종료되는 것은 아니며, 신호를 무시하거나 다음을 사용하여 스크립트에서 처리기를 설정할 수 있습니다.trap내장 명령. 이는 신호를 Ctrl-C보내는 eq 히트 에도 적용됩니다 . (*)SIGINT

기술적으로 말하면, 사례 1~6의 경우,쉘 프로세스스크립트 실행은 자동으로 종료됩니다(즉, 프로세스 호출 exit()). 반면에 상대방의 입장에서는스크립트그 자체로, 또는 문법적 오류로 인한 종료는 비자발적이라고 불릴 가능성이 높습니다 set -e. set -u그러나 쉘 스크립트는 쉘 인터프리터와 동일하지 않습니다.

1~3에서는 성공적인 완료에는 0 종료 상태를 사용하고 실패에는 0이 아닌 값을 사용하는 것이 관례입니다. 0이 아닌 값의 정확한 의미는 유틸리티에 따라 다릅니다. 일부는 0과 1만 사용할 수도 있고, 다른 일부는 상황에 따라 0이 아닌 다른 상태를 사용할 수도 있습니다. 예를 들어, grep를 사용하면 1일치하는 항목이 없음을 나타내고 값보다 크면 1오류가 있음을 나타냅니다. Bash의 내장 함수는 2잘못된 옵션과 같은 오류를 나타내는 데에도 사용됩니다. 유사한 사용자 정의를 사용하는 것이 유용할 수 있지만 스크립트 종료 상태의 의미를 문서화해야 합니다. 종료 상태는 일반적으로 8비트로 제한되므로 범위는 ~ 0입니다 255.

4~6에서는 이런 상황이 보통 일종의 실패로 간주되기 때문에 종료상태가 0이 아니다. 7. 종료 상태가 없습니다. 대신, 신호로 인해 프로세스가 종료되면 wait()시스템 호출은 문제의 신호를 나타냅니다. 상위 프로세스가 셸인 경우 일반적으로 종료 상태 로 표시됩니다 128 + <signal number>(예: 143로 종료되는 하위 프로세스의 경우) SIGTERM.

(* 스크립트와 달리 대화형 쉘은 구문 오류나 .) 로 set -u종료 되지 않습니다 .SIGINT

첫 번째 셸 세션에 있는 경우 일반적으로 이로 인해 셸 CLI 창이 닫힙니다.

터미널 에뮬레이터에 의해 시작된 프로세스가 종료되면 일반적으로 닫힙니다. 그러나 이는 셸의 기능이 아니라 터미널 에뮬레이터에 따라 다릅니다. 터미널 에뮬레이터는 사용자에게 프로그램이 종료되었음을 알리기 위해 창을 열어 두기로 결정할 수 있으며 터미널 에뮬레이터에서 셸 이외의 다른 것을 실행할 수도 있습니다.

일부 하위 세션에 있는 경우 일반적으로 실행을 통해 사용자가 이전 세션으로 돌아갑니다.

대화형 셸을 사용하여 다른 셸을 시작하는 경우 하위 셸이 종료될 때 상위 셸이 계속 실행됩니다. 그러나 다시 말하지만 이것은 셸과는 아무런 관련이 없습니다. 편집기를 시작하거나 대화형 셸에서 명령을 실행하는 경우에도 동일한 일이 발생합니다. 하위 프로세스가 종료되면 상위 셸은 계속해서 사용자의 명령을 받아들입니다.

SHLVLBash는 Bash가 시작될 때마다 1씩 증가하는 변수를 유지하므로 어떤 의미에서는 중첩된 쉘의 내부 아이디어를 가지고 있습니다. 그러나 나는 "부회의"라는 용어가 일반적이라고 생각하지 않습니다. 어떤 형태의 번호 매기기는 말할 것도 없습니다. (내 생각 에는 . SHLVL에서 초기화된 것 같습니다 1.)

답변2

출구의 "모드"는 실제로 다르지 않습니다.

인수 없이 사용하면 exit이전 명령의 반환 코드가 반환 코드로 사용됩니다. 이것이 스크립트의 마지막 명령인 경우 source스크립트가 작성되지 않는 한 실제로는 NOOP입니다.

exit 0반환 코드를 0오류가 아닌 상태에 대한 표준 종료 코드인 으로 명시적으로 설정합니다.

0이 아닌 숫자를 사용하면 동일한 작업이 수행됩니다. 즉, 반환 코드를 지정된 값으로 설정합니다.

지시문 없이 스크립트가 exit종료되면 해당 명령에 의해 실행된 최종 명령의 종료 코드가 사용됩니다.

트랩에 명령문을 포함하면 trap '[...]' EXIT스크립트가 실제로 종료되기 전에 트랩이 실행(포함된 명령 포함)되므로 해당 명령문이 대체됩니다.exitexit

답변3

0, 1, 2 외에도 더 많은 종료 코드가 있습니다. 보다:

종료 코드에 대해 생각할 때 스크립트가 항상 의심되는 곳에서 끝나는 것은 아니라는 점을 기억해야 합니다. 완료되기 전에 신호에 의해 종료되거나 Ctrl- 를 눌러 예기치 않은 입력 종결자로 인해 종료 D되어 예기치 않은 종료가 발생할 수 있습니다. 따라서 스크립트, 특히 대량의 코드를 반환하는 스크립트에 대한 올바른 이해와 분석이 필요합니다.

답변4

질문을 올바르게 이해했는지 잘 모르겠지만 다른 진행 방법을 찾고 있는 것 같습니다.종료바꾸다그만두다?

  • 말한 대로 쉘(또는 쉘이 실행하는 명령)을 종료할 수 있습니다(예: 대화형 쉘이 EoF를 만나면 종료됩니다. 쉘이 실행하려는 명령 실행을 마치면(스크립트가 종료됨), 또한 종료되거나 종료가 발생하는 경우(예: 셸의 "exit 2"로 인해 코드 2로 종료됨)

  • 상위 셸에서 프로세스를 분리하기 위해 "nohup"(또는 그 변형)을 실행하지 않고 상위 셸이 종료되면 "HUP"가 나타날 수 있습니다.

  • Ctrl-C를 받을 수 있습니다.

  • 메모리/CPU/무언가가 부족할 수 있습니다(fd?)

  • kill -9 같은 것을 얻을 수도 있습니다. (이상하더라도 스크립트 자체는 "kill -9 $$" 자체를 수행할 수 있습니다...)

  • 케이싱은 왼쪽 끝의 갑작스러운 종료로 인해 파손된 파이프의 오른쪽에 있을 수 있습니다.

  • 더 많은 경우가 있을 것 같은데...

이들 각각은 프로그램/셸을 종료하기로 되어 있으며 각각은 약간 다릅니다(그리고 종료하기 전에 일부 작업을 수행하거나 완전히 종료되는 것을 방지하기 위해 일부를 잡을 수 있습니다(예를 들어 ctrl-C의 경우 INT 신호))

관련 정보