"kill -PIPE $$"와 "exit 1"의 차이점은 무엇입니까?

"kill -PIPE $$"와 "exit 1"의 차이점은 무엇입니까?

내 Bash 스크립트에서는 다음 구문을 사용하여 Bash 스크립트를 종료합니다.

kill -PIPE $$

때때로 스크립트의 함수나 내부 셸 내에서 exit 1Bash 스크립트가 실제로 종료되지 않기 때문에 이것을 사용합니다.

그래서 kill나는 exit 1.

것 같다

exit 1

그리고

kill -PIPE $$

거의 동일합니다. 내 가정이 사실인가요?

둘째, kill -PIPE $$이 구문을 사용할 때 위험이 있습니까?

답변1

exit 1예를 들어, 종료 코드 1을 사용하여 현재 하위 셸 환경을 종료합니다.

sh -c '(echo 1; exit 1; echo 2); echo 3'

그러면 exit 1측면에서 코드를 실행하는 하위 쉘이 종료되므로 (...)출력 2이 없으며 상위 쉘 프로세스가 에코를 재개합니다 3.

kill -s PIPE "$$"1 현재 스크립트를 해석하고 있는 쉘 인터프리터를 실행하는 프로세스에 SIGPIPE 신호를 보냅니다. 기본적으로 SIGPIPE 신호는 프로세스를 종료시키고, 프로세스가 SIGPIPE에 의해 종료되었다는 사실이 종료 상태에 반영됩니다.

그래서:

sh -c '(echo 1; kill -s PIPE "$$"; echo 2); echo 3'

SIGPIPE 신호는 하위 셸 프로세스에서 상위 프로세스(실행 프로세스 sh)로 전송됩니다. 상위 프로세스는 종료되고 출력이 생성되지 않지만 3하위 셸 프로세스는 백그라운드에서 계속 실행되어 출력을 생성합니다 2.

bashzsh또는 쉘(및 Bourne과 같은 다른 쉘)에서 명령을 실행 하면 해당 쉘은 $?인수(마지막 명령의 종료 상태에 대한 내부 표현)를 128 + SIGPIPE(대부분의 시스템)인 141과 같은 것으로 설정합니다. 위는 13)이다.

이제 SIGPIPE는 읽기 끝(깨진 파이프/소켓)이 없는 파이프나 소켓에 쓰려고 하는 프로세스에 시스템이 보내는 신호이므로 여기로 보내는 것은 약간 오해의 소지가 있습니다. 프로세스의 관리 종료를 위해 예약된 신호는 SIGTERM이며 kill기본적으로 전송되는 신호입니다.

이제 SIGTERM 대신 SIGPIPE를 사용하려는 이유 중 하나는 bash작업 중 하나가 신호에 의해 종료될 때 메시지를 인쇄하는 유사한 쉘이 있고 일반적으로 SIGPIPE에서는 그렇게 하지 않는다는 것입니다. SIGPIPE에 의해 종료되는 프로세스에 유용하다고 해서 반드시 cmd | head -n 1에서와 같은 문제가 있다는 의미는 아니므로 SIGPIPE를 사용하는 것이 이러한 메시지를 방지하는 한 가지 방법입니다.

bash-4.4$ /bin/kill 0
Terminated
bash-4.4$ /bin/kill -s PIPE 0
bash-4.4$

비대화형인 경우에도:

$ bash -c 'sh -c "kill \$\$"; exit'
bash: line 1:  6665 Terminated              sh -c "kill \$\$"
$ bash -c 'sh -c "kill -s PIPE \$\$"; exit'
$

1 여기에 추가하세요주변에 따옴표가 없습니다.$$신뢰성과 사용을 위해표준(POSIX에서는 선택 사항이 아님) kill -s PIPE이식성 구문( kill -PIPE대부분의 시스템에서도 작동하지만)

관련 정보