명명 된 파이프에 대한 자동 EOF 방지 및 원하는 경우 EOF 전송


12

주어진 스트림에서 EOF를 읽을 때 자동으로 종료되는 프로그램이 있습니다 (다음 경우 stdin).
이제 이름이 지정된 파이프를 만들고 프로그램의 표준 입력을 연결하는 셸 스크립트를 만들고 싶습니다. 그런 다음 스크립트는 및 (및 종료시 자동으로 EOF를 생성하는 기타 도구)를 사용하여 파이프에 여러 번 씁니다 . 내가 직면하고있는 문제는 첫 번째 작업이 완료되면 EOF를 파이프로 보내고 프로그램을 종료하는 것입니다. 다음과 같은 것을 사용 하면 프로그램을 종료하려고 할 때 EOF를 보낼 수 없습니다. 균형 잡힌 솔루션을 연구하고 있지만 아무 소용이 없습니다. EOF를 방지하는 방법과 EOF를 수동으로 전송하는 방법을 이미 찾았지만 조합 할 수는 없습니다. 힌트가 있습니까? echocatechotail -f

#!/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

답변:


13

다른 사람들이 지적했듯이, 파이프의 독자는 작가가 남아 있지 않으면 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
exec 3>P원인 이 bash에 걸려 왜?
Wang

@Wang 그것은해서는 안됩니다. 그렇다면 질문의 POC 코드와 같은 일을하지 않을 것입니다. 내가 막을 것이라고 생각할 수있는 유일한 이유는 대신에 뭔가를하고 bash가 파이프에 쓰려고하는 exec 2>P추적 모드가 켜져 있지만 ( set -x), 독자가 없기 때문에 기다리는 것을 차단하기 때문입니다. 읽을 거리.
패트릭

1
@Wang @Patrick 실제로 exec 3>P내 컴퓨터의 bash에서 중단됩니다. 에서 읽을 프로세스가 없기 때문입니다 P. 따라서, 용액을 스왑 라인이었다 exec 3>P하고 program < P &(즉, 프로그램이 배경에서 실행되도록 앰퍼샌드 추가).
macieksk

2

마지막 작가가 사라지면 파이프에 EOF가 수신됩니다. 이것을 피하려면, 항상 라이터 (쓰기 용으로 파이프가 열려 있지만 실제로 아무것도 쓰지 않는 프로세스)가 있는지 확인하십시오. EOF를 보내려면 예비 작가를 떠나야합니다.

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

0

프로그램이 "종료 시간"을 의미하는 EOF와 "작가가 완료되었지만 다른 사람으로부터 더 많은 정보가 입력 될 수 있음"을 의미하는 EOF를 구별 할 수있는 방법이 없습니다.

프로그램의 동작을 수정하는 기능이 있다면 무한 루프 (EOF까지 1 회 반복)에서 판독하고 "종료 시간"을 의미하는 특정 명령 문자열을 보내십시오. 해당 문자열을 보내는 것이 send_eof질문 의 명령 작업입니다 .

다른 옵션 :

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

또는

{ echo some stuff; cat more_stuff.txt; } >P
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.