zsh에서 cat <(cat) vs cat | 고양이 대 고양이 = (고양이)?


18

내가 예상 cat <(cat)cat | cat같은 일을 : 표준 출력 stdin에서 라인을 복사합니다. 내 이해는 둘 다 cat서브 쉘에서 실행 하고 서브 쉘 cat의 stdout을 임시 명명 된 파이프로 cat리디렉션 한 다음 stdin이 파이프로 리디렉션 된 현재 쉘에서 다른 것을 실행 한다는 것입니다.

대신 cat <(cat)터미널에 입력 할 수 있지만 입력 라인이 복사 ^D되지 않고 신호를 보내지 않습니다 EOF. cat | cat그래도 예상대로 작동합니다.

추가 실험으로 cat =(cat)와 비슷한 어려움이 있는지 확인 cat <(cat)했지만 예상대로 작동합니다 ^D. 한 번에 stdout 까지 모든 stdin 이 복사됩니다.

누구든지 zsh가 후드에서하는 일을 이해하도록 도울 수 있습니까?

답변:


23
  1. a | b커넥트 STDOUT에서 aSTDIN에서 b바로 사용하여 dup/dup2. 두 명령 모두 병렬로 실행됩니다.

  2. a =(b)인수를 a임시 파일 이름으로 바꿉니다 . 임시 파일을 생성해야 b하기 전에 실행 a됩니다.a

  3. a <(b)인수를 a명명 된 파이프 로 바꿉니다 . ab병렬로 실행합니다. 이것은 이제 조금 복잡해집니다.

    b백그라운드에 있으며 터미널에서 읽을 수 없습니다. strace -p $PID두 번째 고양이 프로세스에 연결하여 프로세스를 확인 하여 직접 테스트 할 수 있습니다 .

    a그 동안 명명 된 파이프에서 읽으려고하지만 읽을 b수없는 내용을 읽을 수 없습니다.

    • 이것은 기본적으로 a읽을 수는 b있지만 b읽을 STDIN수없고 쓸 수없는 교착 상태가 있음을 의미합니다.a

man bash의 백그라운드 프로세스 및 터미널에 대한 추가 정보 :

작업 제어에 대한 사용자 인터페이스 구현을 용이하게하기 위해 운영 체제는 현재 터미널 프로세스 그룹 ID 개념을 유지합니다 . 이 프로세스 그룹 (프로세스 그룹 ID가 현재 터미널 프로세스 그룹 ID와 동일한 프로세스)의 구성원은 SIGINT 와 같은 키보드 생성 신호를 수신 합니다. 이러한 프로세스는 포 그라운드 에 있다고합니다 . 배경프로세스는 프로세스 그룹 ID가 터미널과 다른 프로세스입니다. 이러한 프로세스는 키보드 생성 신호에 영향을받지 않습니다. 포 그라운드 프로세스 만 읽거나 사용자가 stty tostop으로 지정하면 터미널에 쓸 수 있습니다. stty tostop이 유효 할 때 쓰기를 시도하는 백그라운드 프로세스 는 커널의 터미널 드라이버에 의해 SIGTTIN (SIGTTOU) 신호를 전송합니다 .


감사합니다.이 문제는 많이 해결되었습니다!
Alan O'Donnell

1
대화식이 아닌 경우 zsh는 백그라운드 명령 의 표준 입력 (에 포함 된 명령 포함 <(cmd))을로 리디렉션 /dev/null하므로 동작이 달라집니다 ( zsh -c 'cat <(cat)'즉시 리턴되고 아무 것도 출력하지 않음).
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.