
Eu estava brincando no terminal e fiz isso:
printf 'some string\n' | {
tee /dev/fd/3 | {
: && sed 's/some/string/'
}
} 3>&0
Fiquei realmente surpreso quando me deparei com uma tela cheia de:
string string
string string
string string
...
Isso durou praticamente uma eternidade. Eu reduzi um pouco e, para demonstrar melhor, talvez tente isto:
echo | tee /dev/fd/0 | sed =
Para mim, apresenta resultados como:
<num>
#blank
<num+1>
#blank
...
E assim por diante. Nas poucas vezes que tentei, quando consegui acertar CTRL+, Cestava na linha 200k+. Eu tentei isso em bash
, dash
, sh
e zsh
e todos apresentam os mesmos resultados.
O que está acontecendo lá? Como os descritores de arquivos estão passando por |pipe
entre processos separados, o que eu pensava? Este comportamento é confiável e/ou esperado? Existem outras maneiras de gerar esse efeito?
Para referência:
echo '#blank' | {
uname -r
readlink -f /dev/fd/0
tee /dev/fd/0
} | sed '=;5q'
SAÍDA
1
3.14.6-1-ARCH
2
/proc/24925/fd/pipe:[5851017]
3
#blank
4
#blank
5
#blank
Responder1
/dev/fd/0
é a entrada padrão do processo atual; tee
grava sua entrada nos arquivos que você fornece e no stdout. O mesmo tee
ocorre com a leitura de uma linha (em branco) e, em seguida, a gravação dessa linha em stdout ( sed
) e em sua própria entrada, onde ele lê a linha que acabou de escrever, grava-a em stdout e em sua própria entrada, etc., criando um loop infinito de ( vazio) linhas*. O sed
comando apenas imprime o número da linha e depois a linha.
echo --> tee --> sed
^---+
* Quando for fornecida mais entrada do que apenas um simples echo
, este comando fará um loop sobre a entrada, repetindo-a indefinidamente.
Nota: OSX (BSD) não permite escrever em /dev/fd/0
, então você não pode fazer isso.