쉘 스크립트에 이와 같은 것이 있다고 가정 해 봅시다.
command1 | command2
command2
이제 종료시 어떻게 종료 되도록 할 수 있습니까 command1
?
편집하다:
command2
이는 일반적으로 표준 입력에서 읽으려고 할 때 기본적으로 발생하며 0을 반환합니다. 구체적인 예가 있나요?
여기 있어요:echo test | xmobar
xmobar
이것도 대용으로 사용해도 될 것 같아요
#!/bin/sh
while :; do :; done
답변1
이 댓글파이프의 다른 쪽 끝이 닫힐 때 프로그램이 어떻게 종료되는지(또는 종료되지 않는지) 설명하십시오.
파이프를 닫으면 아무 것도
command1
알려주지 않습니다 . 파이프를 읽고, 비우고, EOF를 얻을command2
때까지command2
아무 일도 일어나지 않습니다 . 그럼에도 불구하고 아직 할 일이 남아 있다면 종료할 필요는 없습니다. 마찬가지로,command2
먼저 종료 되면command1
파이프에 쓸 때까지 검색되지 않으며, 이 시점에서SIGPIPE
이를 포착하면 다른 작업도 계속할 수 있습니다.
그래서 이것은 자동으로 일어날 수 있는 일입니다. 이제 귀하의 질문은 다음과 같습니다
command1 | command2
[ 알려지지 않았거나 원하지 않았 더라도 ] 종료 시
command2
종료되도록 하려면 어떻게 해야 합니까 ?command1
command2
쉘이 별도의 프로세스 그룹에서 파이프를 실행하는 경우 전체 그룹을 종료해 보십시오. 예를 들어 Bash는 작업 제어가 활성화된 경우( set -m
) 이 작업을 수행합니다. 대화형 셸(지원하는 시스템)에서는 기본적으로 활성화되어 있지만 스크립트에서는 활성화되어 있지 않습니다.
샘플 코드:
#!/bin/bash
set -m
( command1; kill -s INT 0 ) | command2
전체 파이프라인은 첫 번째 부분의 PID와 동일한 PGID(프로세스 그룹 ID)를 갖는 별도의 프로세스 그룹에서 실행됩니다. 이 경우에는 서브셸입니다. kill 0
자신의 프로세스 그룹에 신호를 보냅니다. 이렇게 하면 종료 후에 신호를 보냅니다 command2
.command1
노트:
- 이는 Bash에
kill
내장되어 있으므로kill
예제에서는 PID와 PGID가 할당된 별도의 프로세스가 없습니다. 따라서 위의 "자체 프로세스 그룹"이라는 문장은 엄밀한 것이 아니라 "서브쉘의 프로세스 그룹"이어야 합니다. 이는 여전히 우리가 사용하려는 정확한 프로세스 그룹입니다. 내장형kill
이든/bin/kill
사용 가능든 둘 중 하나가 가능합니다. command2
자체 프로세스 그룹을 변경할 수 있습니다. 그렇다면 이 솔루션은 작동하지 않습니다.command2
그 신호를 무시하거나 거의 모든 방식으로 처리하는 것이 가능하기 때문입니다 . 귀하의 필요에 맞는 신호를 선택하십시오.kill
종료 후 바로 전화하는 것은command1
시기상조일 수 있습니다.command2
생성된 모든 데이터를 읽고 처리하기 전에 종료 될 수 있습니다 .command1
아마도 모든 데이터를 처리하기를 원할 것입니다.command2
동작 에 따라 지연이 유용할 수 있습니다kill
(예sleep 2; kill …
: ). (범용) Linux는 그렇지 않습니다.실시간 운영체제, 따라서 상황이 심각해지면 고정된 지연이 너무 짧아질 수 있습니다.