"출력" 프로세스가 종료되면 익명 파이프 종료

"출력" 프로세스가 종료되면 익명 파이프 종료

쉘 스크립트에 이와 같은 것이 있다고 가정 해 봅시다.

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종료되도록 하려면 어떻게 해야 합니까 ?command1command2

쉘이 별도의 프로세스 그룹에서 파이프를 실행하는 경우 전체 그룹을 종료해 보십시오. 예를 들어 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는 그렇지 않습니다.실시간 운영체제, 따라서 상황이 심각해지면 고정된 지연이 너무 짧아질 수 있습니다.

관련 정보