camiseta sem fundo?

camiseta sem fundo?

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, she zshe todos apresentam os mesmos resultados.

O que está acontecendo lá? Como os descritores de arquivos estão passando por |pipeentre 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; teegrava sua entrada nos arquivos que você fornece e no stdout. O mesmo teeocorre 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 sedcomando 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.

informação relacionada