손상된 파이프로 인해 Unix 프로세스가 종료되는 원인은 무엇입니까?

손상된 파이프로 인해 Unix 프로세스가 종료되는 원인은 무엇입니까?

마음에 떠오른 몇 가지 옵션은 다음과 같습니다. 어느 것이 올바른지 확실하지 않습니다.

  1. 파이프에서 읽는 동안 I/O 오류가 발생했습니다.
  2. 파이프의 다른 쪽 끝에 쓰는 프로세스가 실패로 종료됩니다.
  3. 파이프에 쓸 수 있는 모든 프로세스가 파이프를 닫았습니다.
  4. 파이프의 쓰기 버퍼가 가득 찼습니다.
  5. 피어가 이중 파이프의 다른 방향을 닫았습니다.
  6. 파이프에서 읽을 수 있는 프로세스가 없기 때문에 쓰기가 실패합니다.
  7. 시스템 호출이 EPIPE 오류를 반환했으며 오류 처리기가 설치되지 않았습니다.

답변1

프로세스는 남아 있는 판독기가 없는 SOCK_STREAM 유형의 파이프(이름이 지정되거나 지정되지 않은) 또는 소켓에 쓰려고 시도할 때 SIGPIPE를 수신합니다.

이는 일반적으로 원하는 동작입니다. 전형적인 예는 다음과 같습니다.

find . | head -n 1

find종료한 후 head(읽기 위해 열려 있던 해당 파이프의 유일한 파일 설명자를 닫은 후) 계속 실행하고 싶지 않습니다 .

명령 은 yes일반적으로 이 신호에 의존하여 종료됩니다.

yes | some-command

"y"는 명령이 종료될 때까지 기록됩니다.

이는 명령이 종료될 때뿐만 아니라 모든 판독기가 파이프에서 fd 읽기를 닫을 때도 발생합니다. 존재하다:

yes | ( sleep 1; exec <&-; ps -fC yes)
      1 2       1        0

서브쉘이 명시적으로 stdin을 닫은 후에는 파이프에서 1(서브쉘), 2(서브쉘 + 절전), 1(서브쉘), 0 fd 읽기가 발생하며 이 시점에서 yesSIGPIPE가 수신됩니다.

위에서 대부분의 쉘은 pipe(2)while 을 ksh93사용 socketpair(2)하지만 이와 관련하여 동작은 동일합니다.

프로세스가 SIGPIPE를 무시하면 쓰기 시스템 호출(일반적 write으로 , pwrite, send... splice)이 오류를 반환합니다 EPIPE. 따라서 손상된 파이프를 수동으로 처리하려는 프로세스는 종종 SIGPIPE를 무시하고 EPIPE 오류에 대해 조치를 취합니다.

답변2

(6)

파이프에서 읽을 수 있는 프로세스가 없기 때문에 쓰기가 실패합니다.

설명자를 복사하고 분기하지 않으면 하나의 프로세스만 시작할 수 있지만 일반적으로 파이프에는 판독기와 기록기가 있으며 둘 중 하나가 연결을 닫으면 파이프가 유효하지 않게 됩니다. 명명된 파이프를 사용하는 경우 여러 연결(직렬)을 가질 수 있지만 이러한 의미에서 각 연결은 새 파이프를 나타냅니다. 따라서 스레드나 프로세스의 "파이프"는 파일 설명자와 동의어입니다.

에서 man 7 pipe:

파이프의 읽기 끝을 참조하는 모든 파일 설명자가 닫힌 경우 write(2)는 호출 프로세스에 대해 SIGPIPE 신호가 생성되도록 합니다. 호출 프로세스가 이 신호를 무시하면 write(2)는 오류 EPIPE와 함께 실패합니다.

따라서 "깨진 파이프"는 저자에게 EOF가 독자에게 있는 것과 같습니다.

답변3

파이프 손상은 쓰기 프로세스 전에 읽기 프로세스가 종료될 때 발생합니다. 그래서 저는 (6)을 선택하겠습니다.

관련 정보