ksh93 tem disciplinas que são normalmente usadas para esse tipo de coisa. Com zsh , você pode seqüestrar o recurso diretório nomeado dinâmico :
Defina por exemplo:
zsh_directory_name() {
case $1 in
(n)
case $2 in
(incr) reply=($((++incr)))
esac
esac
}
Você pode usar ~[incr] para obter um $incr incrementado a cada vez:
$ echo ~[incr]
1
$ echo ~[incr] ~[incr]
2 3
Sua abordagem falha porque, em head -1 /tmp/ints , o head abre o fifo, lê um buffer completo, imprime uma linha, e depois a fecha . Uma vez fechado, o final da escrita vê um cano quebrado.
Em vez disso, você pode fazer:
$ 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
Lá, deixamos o final da leitura aberto no fd 3, e read lê um byte de cada vez, não um buffer completo para ter certeza de ler exatamente uma linha (até o caractere de nova linha).
Ou você poderia fazer:
$ 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
Naquela época, instanciamos um pipe para cada valor. Isso permite retornar dados contendo qualquer número arbitrário de linhas.
No entanto, nesse caso, assim que cat abrir o fifo, o echo e o loop serão desbloqueados, portanto, mais echo poderá ser executado, quando cat ler o conteúdo e fechar o pipe (fazendo com que o próximo echo instancie um novo canal).
Uma solução alternativa poderia ser adicionar algum atraso, como por exemplo, executando um echo externo como sugerido por @jimmij ou adicionando algum sleep , mas isso ainda não seria muito robusto, ou você poderia recriar o nome canalizar após cada echo :
while
mkfifo $fifo &&
echo $((++incr)) > $fifo &&
rm -f $fifo
do : nothing
done &
Isso ainda deixa janelas curtas em que o canal não existe (entre unlink() feito por rm e mknod() feito por mkfifo ), fazendo com que cat falhe e janelas muito curtas em que o pipe foi instanciado, mas nenhum processo será gravado novamente nele (entre write() e close() feito por echo ), fazendo com que cat não retorne nada e janelas curtas em que o pipe nomeado ainda existe, mas nada será sempre abri-lo para gravação (entre o close() feito por echo e o unlink() feito por rm ) onde cat irá travar.
Você pode remover algumas dessas janelas fazendo o seguinte:
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
) &
Dessa forma, o único problema é se você executar vários cat ao mesmo tempo (todos eles abrem o fifo antes que nosso loop de gravação esteja pronto para abri-lo para gravação). Nesse caso, eles compartilharão a echo output. / p>
Eu também aconselho contra a criação de nomes fixos, fifos legíveis para o mundo (ou qualquer arquivo para esse assunto) em diretórios graváveis mundiais como /tmp a menos que seja um serviço a ser exposto a todos os usuários no sistema.