FIFO 파이프가 있는 이 스크립트가 종료되지 않는 이유는 무엇입니까?

FIFO 파이프가 있는 이 스크립트가 종료되지 않는 이유는 무엇입니까?

이 스크립트는 다음과 같습니다.

#!/bin/bash
tmppipe=/tmp/temppipe
mkfifo $tmppipe
echo "test" > $tmppipe
cat $tmppipe
exit

종료되지 않습니다. cat명령이 파이프의 명령을 기다리고 있다고 가정합니다 EOF. 어떻게 보내나요?

답변1

아니 그렇지

echo test > "$tmppipe" # BTW, you've got the quotes in the wrong places

그게 걸려 있어요. 보다 정확하게는 파이프를 실행하기 전에 쓰기 위해 파이프를 여는 쉘입니다 echo.

pipe실행 중인 프로세스 간에 사용할 프로세스 간 통신 메커니즘입니다.동시에. 여기서 open(WR_ONLY)( >)는 다른 프로세스가 읽기 모드를 실행할 때까지 차단됩니다 open.

echo test > "$tmppipe" &
cat < "$tmppipe"

동시에 실행되기 echo때문에 작동합니다 .cat

Linux에서는 다음을 수행하여 벗어날 수 있습니다.

exec 3<> "$tmppipe" 4< "$tmppipe"
echo test >&3
exec 3>&-
cat <&4

이는 Linux에서 파이프의 읽기+쓰기 open( )가 차단되지 않고, by의 출력이 파이프에 들어갈 만큼 작기 때문에 쓰기와 읽기를 순차적으로 수행할 수 있기 때문에 작동합니다.<>test\necho

다음과 같은 더 큰 출력에는 작동하지 않습니다.

exec 3<> "$tmppipe" 4< "$tmppipe"
seq 100000 >&3
exec 3>&-
cat <&4

파이프(현재 Linux 버전에서는 64kiB)를 채우고 seq다른 프로세스가 파이프에서 읽을 때까지 차단됩니다. 이는 cat완료될 때까지 실행되지 않기 때문에 발생하지 않습니다.seq

알아채다:

echo test 1<> "$tmppipe"
cat < "$tmppipe"

명령줄이 파이프를 열고, 테스트를 작성한 다음 파이프를 닫으므로 작동하지 않습니다 echo(열린 파일 설명자가 더 이상 없기 때문에 시스템은 파이프를 파괴합니다). 따라서 다음 cat명령줄은 새 파이프를 인스턴스화하려고 시도합니다(그리고 쓰기 위해 fifo 파일을 열 때까지 차단합니다).

답변2

대답은 분명합니다. 파이프가 잠겨 있고 echo고양이에게 도달하지 않습니다!

파이프는 데이터를 저장하지 않습니다. 프로세스가 파이프에 쓰기를 시도하면 파이프의 다른 쪽 끝에 무언가를 추가하여 읽을 때까지 쓰기가 완료될 수 없습니다.

이 특정 예를 해결하는 한 가지 방법은 다음을 사용하는 것입니다.

echo "test" > $tmppipe &

쓰기 프로세스가 백그라운드에서 실행되도록 합니다. 이렇게 하면 스크립트가 계속 실행되면서 해당 스크립트에 도달하여 cat완료될 수 있을 때까지 기다립니다.

관련 정보