![셸 파이프에서 프로세스 신호 "종료" 메시지 출력을 캡처합니다.](https://linux55.com/image/214428/%EC%85%B8%20%ED%8C%8C%EC%9D%B4%ED%94%84%EC%97%90%EC%84%9C%20%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%20%EC%8B%A0%ED%98%B8%20%22%EC%A2%85%EB%A3%8C%22%20%EB%A9%94%EC%8B%9C%EC%A7%80%20%EC%B6%9C%EB%A0%A5%EC%9D%84%20%EC%BA%A1%EC%B2%98%ED%95%A9%EB%8B%88%EB%8B%A4..png)
프로세스가 신호를 통해 종료되면 사용된 신호 와 유사 Terminated
하거나 이에 따라 달라지는 메시지가 출력됩니다. Killed
이 메시지를 캡처할 수 있나요?
다음 파이프라인을 예로 들어 보겠습니다.
while true; do timeout 2 sleep 5; done
아무것도 출력하지 않고 sleep
2초마다 종료됩니다. 하나를 추가하세요 cat
:
while true; do timeout 2 sleep 5 | cat; done
이제 Terminated
2초마다 출력되지만 cat
볼 수 없습니다. 로 바꾸면 cat
파일 tee somefile
이 여전히 비어 있습니다.
2>&1
명령줄의 다양한 위치에서 리디렉션을 시도했지만 출력을 Terminated
파일로 가져올 수 없습니다.
libc
루프가 아닌 터미널 쉘에 연결된 명령을 통해 출력되는 것 같습니다 .
Terminated
유사한 출력을 파이프에 넣을 수 있습니까 ?
sleep
(궁극적으로 the를 a로, curl
the를 스크립트로 바꾸고 출력과 메시지를 처리하고 싶습니다 .)cat
awk
curl
Terminated
답변1
분석하다
예, 이것이 쉘이 인쇄하는 것입니다 Terminated
. 해고되었기 때문에 timeout 2 sleep 5 | cat
볼 때 . 그리고 나Terminated
cat
하다의미는 입니다 cat
.
이에 대한 설명은 다음과 같습니다.내 다른 답변은 다음과 같습니다.. timeout
귀하의 경우에는 SIGTERM을 전체 프로세스 그룹에 보내십시오.sleep
그리고 cat
.
프로세스 그룹 timeout
도 포함됩니다. 자체 신호에 의해 종료되지 않는 것 같습니다. 이것이 timeout
단독이 셸을 인쇄하지 않는 이유입니다. 그러나 이렇게 하면 SIGKILL을 포착하거나 무시할 수 없기 때문에 쉘에서 이를 볼 수 있습니다. SIGKILL로 죽이면 스스로 죽고 쉘이 반응합니다.timeout 2 sleep 5
Terminated
timeout -s KILL 2 sleep 5
Killed
timeout
sleep
그래서 그것이 당신이 관찰하는 것이 cat
가장 중요 합니다 Terminated
. 이제 , sleep
으로 바꾸면 합계 curl
가 종료 됩니다 . 그러나 메시지를 인쇄하는 것은 셸이기 때문에 중요하지 않습니다. 정말로 메시지를 캡처하려면 파이프에서 캡처해야 합니다.cat
awk
timeout
curl
awk
awk
뒤쪽에껍데기.
해결책
정말로 메시지를 캡처하려면 awk
메시지를 인쇄하는 셸 뒤에 파이프를 추가해야 합니다. 그리고 종료된 "피해자" 프로세스가 필요하며, 이 프로세스가 없으면 메시지가 없습니다. 그리고 PID와 동일한 PGID를 가진 프로세스 그룹에서 실행되는 쉘이 필요합니다 timeout
. 이는 메커니즘에 중요하기 때문입니다(링크된 답변 참조). 예를 들어 awk
다음 파이프라인에서는 메시지가 성공적으로 처리되어야 합니다.
bash -ic 'timeout 2 sleep 5 | cat' 2>&1 | awk '{print "This is the message: "$0}'
-i
그것은 중요합니다. 그것 없이는 timeout
우리의 불쌍한 비난자들을 죽이지 않을 것입니다 cat
. 엄밀히 말하면 이는 대화형 또는 비대화형 Bash와는 아무런 관련이 없습니다. 여기에는 작업 제어 활성화(대화형 Bash에서 기본적으로 활성화됨) 또는 비활성화(비대화형 Bash에서 기본적으로 활성화됨)가 포함됩니다. 따라서 이것은 또한 작동합니다:
bash -c 'set -m; timeout 2 sleep 5 | cat' 2>&1 | awk '{print "This is the message: "$0}'
더욱 우아한 솔루션
원하는 것을 수행하는 더 쉬운 방법이 있습니다. 결국 스크립트에서 실행하려는 경우 스크립트를 해석하는 셸이 해당 명령에 대해 별도의 프로세스 그룹을 생성해서는 안 된다는 사실을 활용할 수 있습니다. 비대화형 스크립트에서는 timeout … | awk
종료되지 않습니다 awk
.
이제 당신에게 필요한 것은 timeout -v
그것이 무엇을 하는지 듣는 것뿐입니다. 다음 예제는 비대화형 스크립트로 실행되도록 설계되었습니다. 대화형 Bash에서 테스트하려면 가능하지만 먼저 작업 제어( set +m
)를 비활성화해야 합니다. 스크립트는 다음과 같습니다.
#/bin/sh
timeout -v 2 sleep 5 2>&1 | awk '{print "This is the message: "$0}'
sleep
사용. . . 교체 curl
. 탐지하려고 하기보다는 awk
찾아보아야 합니다 .timeout: sending signal TERM to command '…'
Terminated