
주어진 스트림(다음 경우에는 stdin)에서 EOF를 읽을 때 자동으로 종료되는 프로그램이 있습니다.
이제 명명된 파이프를 생성하고 프로그램의 표준 입력을 여기에 연결하는 쉘 스크립트를 만들고 싶습니다. 그런 다음 스크립트는 파이프에 씁니다.여러번echo
and cat
(및 종료 시 자동으로 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