2011-07-26 1 views
7

LS :명명 된 파이프가 스크립트에서 중간에 닫힙니 까?

prwx------ 1 root root 0 fifo 

write.sh :

#! /bin/bash 
while true; 
do 
    echo "blah" > fifo 
done 

read.sh :

#! /bin/bash 
while true; 
do 
    cat fifo 
done 

나는 하나 write.sh을 실행하고 다른 하나는 read.sh를 실행, 두 터미널 열려 있습니다. 처음에 write.sh을 시작하면 중단됩니다 (중단해야 함). 그런 다음 다른 터미널로 가서 read.sh을 시작하면 "blah" 번을 인쇄하고 내 write.sh이 멈 춥니 다. 쓰기 스크립트가 멈추는 이유는 무엇입니까? 이것은 파이프를 조금이라도 더 잘 이해하려고 시도하는 작은 테스트입니다. 왜냐하면 모든 로그를 파이프로 보내서 파일에 쓰기 전에 분석 할 수 있기 때문입니다.

무엇이 여기에 있습니까?

답변

5

여기에는 경쟁 조건이 있습니다. 어떤 스크립트가 먼저 내부 루프 명령을 실행하는지 (cat과 echo 각각) 차단하고 다른 스크립트가 내부 루프 명령을 실행하기를 기다립니다. 그러나 일단 스크립트가 동기화되면 cat이 echo()를 실행하기 전에 cat에서 close()를 호출하면 echo에 SIGPIPE가 전송되고 스크립트가 종료됩니다. 독자가 닫은 파이프에는 쓸 수 없습니다.

cat을 사용하여 while 루프 대신 tail -f로 독자를 변경하면 판독기가 영구적으로 FIFO를 열고 닫는 대신 판독기가 계속 작동하므로 SIGPIPE를 얻지 않아야합니다.

참조 : man fifo

+0

완벽! 감사. – n0pe

5

당신은 또한 먼저 읽기 파일 설명하고 fifo에 쓰기 파일 기술자를 열 수 비 차단 배관 동작을 얻을 수 있습니다.

# cf. https://stackoverflow.com/questions/2776994/tee-a-pipe-asynchronously 
(
rm -f fifo 
mkfifo fifo 
exec 3<fifo # open fifo for reading 
trap "exit" 1 2 3 15 
exec cat fifo | nl 
) & 
bpid=$! 

(
exec 3>fifo # open fifo for writing 
trap "exit" 1 2 3 15 
while true; 
do 
    echo "blah" > fifo 
done 
) 
#kill -TERM $bpid 

은 참조 : How do I use exec 3>myfifo in a script, and not have echo foo>&3 close the pipe?