ksh93
이런 종류의 일에 일반적으로 사용되는 분야가 있습니다. 을 사용 zsh
하면 동적으로 명명 된 디렉토리 기능을 가로 챌 수 있습니다 .
예를 들어 정의하십시오.
zsh_directory_name() {
case $1 in
(n)
case $2 in
(incr) reply=($((++incr)))
esac
esac
}
그런 다음 매번 ~[incr]
증분을 얻는 데 사용할 수 있습니다 $incr
.
$ echo ~[incr]
1
$ echo ~[incr] ~[incr]
2 3
에서 head -1 /tmp/ints
head가 fifo를 열고 전체 버퍼를 읽고 한 줄을 인쇄 한 다음 닫기 때문에 접근 방식이 실패 합니다 . 일단 닫으면 쓰기 끝에서 파이프가 파손 된 것을 볼 수 있습니다.
대신 다음 중 하나를 수행 할 수 있습니다.
$ fifo=~/.generators/incr
$ (umask 077 && mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo)
$ seq infinity > $fifo &
$ exec 3< $fifo
$ IFS= read -rneu3
1
$ IFS= read -rneu3
2
거기에서, 우리는 판독 끝을 fd 3에서 열어두고 read
한 번에 한 바이트 씩 읽습니다. 완전한 버퍼가 아니라 정확히 한 줄을 읽습니다 (줄 바꿈 문자까지).
아니면 할 수 있습니다 :
$ fifo=~/.generators/incr
$ (umask 077 && mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo)
$ while true; do echo $((++incr)) > $fifo; done &
$ cat $fifo
1
$ cat $fifo
2
그때 우리는 모든 가치에 대해 파이프를 인스턴스화합니다. 임의의 수의 행을 포함하는 데이터를 리턴 할 수 있습니다.
그러나이 경우 cat
fifo 를 열 자마자 echo
and 및 루프가 차단되지 않으므로 내용을 읽고 파이프를 닫을 echo
때까지 더 많은 것을 실행할 수 있습니다 cat
(다음 echo
은 새 파이프를 인스턴스화합니다).
해결 방법은 echo
@jimmij가 제안한 것처럼 외부 를 실행하거나 일부를 추가하는 것과 같이 약간의 지연을 추가 sleep
하는 것이 될 수 있지만 여전히 강력하지는 않지만 각각 후에 명명 된 파이프를 다시 만들 수 있습니다 echo
.
while
mkfifo $fifo &&
echo $((++incr)) > $fifo &&
rm -f $fifo
do : nothing
done &
즉 여전히 (사이에 파이프가 존재하지 않는 짧은 창 잎 unlink()
수행 rm
과 mknod()
수행 mkfifo
의 원인이) cat
실패하고 사이 (파이프가 인스턴스화되고 있지만 프로세스가 이제까지 그것을 다시 쓸 것이다 매우 짧은 창문 write()
과를 close()
수행 echo
원인) cat
명명 된 파이프가 여전히 존재하지만 사이에 아무것도 이제까지 (작성을 위해 그것을 열지 곳 아무것도 돌려주지하고, 짧은 창 close()
에 의해 수행 echo
하고, unlink()
수행 rm
경우) cat
중단됩니다.
다음과 같이 수행하여 해당 창 중 일부를 제거 할 수 있습니다 .
fifo=~/.generators/incr
(
umask 077
mkdir -p $fifo:h && rm -f $fifo && mkfifo $fifo &&
while
mkfifo $fifo.new &&
{
mv $fifo.new $fifo &&
echo $((++incr))
} > $fifo
do : nothing
done
) &
그런 식으로, 유일한 문제는 동시에 여러 고양이를 실행하는 경우 (쓰기 루프가 쓰기 위해 열 준비가되기 전에 모두 fifo를 여는 경우) echo
출력 을 공유하는 것 입니다.
또한 /tmp
시스템의 모든 사용자에게 노출되는 서비스가 아닌 한 쓰기 가능한 디렉토리에 고정 된 이름, 읽을 수있는 fifo (또는 해당 파일)를 작성 하지 않는 것이 좋습니다.