자동 EOF가 명명된 파이프로 전송되는 것을 방지하고 필요할 때 EOF를 보냅니다.

자동 EOF가 명명된 파이프로 전송되는 것을 방지하고 필요할 때 EOF를 보냅니다.

주어진 스트림(다음 경우에는 stdin)에서 EOF를 읽을 때 자동으로 종료되는 프로그램이 있습니다.
이제 명명된 파이프를 생성하고 프로그램의 표준 입력을 여기에 연결하는 쉘 스크립트를 만들고 싶습니다. 그런 다음 스크립트는 파이프에 씁니다.여러번echocat(및 종료 시 자동으로 EOF를 생성하는 기타 도구)를 사용하세요 . 내가 직면한 문제는 첫 번째 작업이 echo완료되면 EOF를 파이프로 보내고 프로그램이 종료된다는 것입니다. 그런 것을 사용하면 tail -f프로그램을 종료하려고 할 때 EOF를 보낼 수 없습니다. 균형잡힌 해결책을 찾기 위해 노력하고 있지만 소용이 없습니다.
EOF를 방지하는 방법과 EOF를 수동으로 보내는 방법을 알아냈는데, 합칠 수는 없습니다. 어떤 팁이 있나요?

#!/bin/sh
mkfifo P
program < P & : # Run in background
# < P tail -n +1 -f | program
echo some stuff > P # Prevent EOF?
cat more_stuff.txt > P # Prevent EOF?
send_eof > P # How can I do this?
# fg

답변1

다른 사람들이 지적했듯이 파이프 판독기는 작성자가 없으면 EOF를 받습니다. 따라서 해결책은 항상 작성자가 이를 켜도록 하는 것입니다. 작성자는 아무 것도 보낼 필요가 없으며 열기만 하면 됩니다.

쉘 스크립트를 사용하고 있으므로 가장 간단한 해결책은 쓰기를 위해 파이프를 열도록 쉘에 지시하는 것입니다. 그런 다음 완료되면 닫습니다.

#!/bin/sh
mkfifo P
exec 3>P # open file descriptor 3 writing to the pipe
program < P
# < P tail -n +1 -f | program
echo some stuff > P
cat more_stuff.txt > P
exec 3>&- # close file descriptor 3

마지막 줄을 생략하면 스크립트가 종료될 때 파일 설명자 3이 자동으로 닫힙니다(따라서 독자는 EOF를 받게 됩니다). 편의성 외에도 이는 스크립트가 조기에 종료되는 경우에도 어느 정도 보안을 제공합니다.

답변2

파이프라인은 마지막 작성자가 사라지면 EOF를 수신합니다. 이를 방지하려면 항상 작성기(쓰기를 위해 파이프를 열지만 실제로는 아무것도 쓰지 않는 프로세스)가 있는지 확인하세요. EOF를 보내려면 보유 작성자를 사라지게 만드세요.

mkfifo P
while sleep 1; do :; done >P &
P_writer_pid=$!
send_eof_to_P () {
  kill $P_writer_pid
}

답변3

프로그램은 "종료할 시간이다"를 의미하는 EOF와 "쓰기가 완료되었지만 다른 사람의 입력이 있을 수 있습니다"를 의미하는 EOF를 구분할 수 없습니다.

프로그램의 동작을 수정할 수 있는 능력이 있다면 무한 루프(EOF까지 지속되는 한 번의 반복)를 읽고 "종료 시간"을 나타내는 특정 명령 문자열을 보낼 수 있습니다. 해당 문자열을 보내는 것은 send_eof귀하의 질문에 있는 명령의 작업 입니다 .

또 다른 옵션:

( echo some stuff; cat more_stuff.txt ) >P

또는

{ echo some stuff; cat more_stuff.txt; } >P

관련 정보