fifo에서 입력을 리디렉션할 때 stdout이 플러시되지 않는 이유는 무엇입니까?

fifo에서 입력을 리디렉션할 때 stdout이 플러시되지 않는 이유는 무엇입니까?

프롬프트 메시지를 표시하고 사용자가 텍스트를 입력할 때까지 기다리는 프로그램이 있습니다.

$ program
Input a line of text: <aaaa>
Some more output.
$

이제 다음과 같이 FIFO를 통해 프로그래밍 방식으로 이 입력을 제공할 수 있기를 원합니다.

$ program < fifo

하지만 .stdout 에 입력을 제공할 때까지 프롬프트가 나타나지 않습니다 fifo.

다음으로 나는 내 프로그램과 매우 간단하게 동등한 것을 시도했습니다. 그것은 다음과 같습니다:

$ echo aaaa < fifo

여기에서도 aaaa입력이 제공될 때까지 나타나지 않습니다.fifo

질문:stdinFIFO를 사용할 때 입력이 올 때까지 출력을 기다리게 하려면 어떻게 해야 합니까 ?stdout

답변1

FIFO는 셸에 의해 열리지만 다른 프로세스에서 쓰기 위해 FIFO를 열 때까지 해당 시작이 차단됩니다. 리디렉션이 처리되므로앞으로명령이 실행된 후에는 쉘 호출이 반환될 때까지 프로그램이 실행되지 않습니다 open(). 이는 문서화된 동작입니다.C open()라이브러리 함수(쉘에서 사용됨):

O_NONBLOCK

O_RDONLY다음을 사용하거나 설정하여 FIFO를 켤 때 O_WRONLY:

  • O_NONBLOCK설정된 경우 open()읽기 전용이 즉시 반환됩니다. open()현재 읽기 위해 파일을 열어 놓은 프로세스가 없으면 쓰기 전용은 오류를 반환합니다.

  • O_NONBLOCK지우 면 open()읽기 전용 호출 스레드는 스레드가 쓰기 위해 파일을 열 때까지 차단되어야 합니다.. 쓰기 전용은 open()스레드가 읽기 위해 파일을 열 때까지 호출 스레드를 차단해야 합니다.

따라서 쉘은 O_NONBLOCKFIFO를 열 때 분명히 이를 사용하지 않습니다.

해결책:

  1. cat fifo | program

    catFIFO에서 파일 끝까지 읽은 후 종료합니다.

  2. tail -f fifo | program

    tail파일이 끝날 때까지 FIFO에서 읽은 다음 종료될 때까지 더 많은 콘텐츠를 기다리며 정지합니다.

이들 중 귀하의 상황에 가장 적합한 것은 부분적으로 상대방이 FIFO에 쓰는 내용과 작성 방법에 따라 달라집니다.

세 번째 해결책은 필요할 때 프로그램이 FIFO를 열도록 하는 것입니다.


~에 따르면기본원리부분sh, 쉘은 표준 입력을 차단으로 설정해야 합니다. 왜냐하면...

쉘이 이 플래그를 재설정하지 않으면 아직 입력 데이터를 사용할 수 없기 때문에 즉시 종료되며 이는 파일 끝과 동일하게 처리됩니다.

관련 정보