футболка без дна?

футболка без дна?

Я просто игрался в терминале и сделал следующее:

printf 'some string\n' | {
    tee /dev/fd/3 | {
        : && sed 's/some/string/'
    }
} 3>&0

Я был очень удивлен, когда увидел на экране следующее:

string string
string string
string string
...

Это продолжалось практически вечность. Я немного сократил его, и для лучшей демонстрации, может быть, попробую это:

echo | tee /dev/fd/0 | sed =

Для меня это выглядит примерно так:

<num>
#blank
<num+1>
#blank
...

И так далее. Несколько раз я пробовал это, когда я мог нажать CTRL+, Cя был на линии 200k+. Я пробовал это в bash, dash, sh, и zshи все представляют те же результаты.

Что там происходит? Как дескрипторы файлов передаются |pipeмежду, как я думал, отдельными процессами? Это надежное и/или ожидаемое поведение? Есть ли другие способы вызвать этот эффект?

Для справки:

echo '#blank' | {
    uname -r
    readlink -f /dev/fd/0
    tee /dev/fd/0
} | sed '=;5q'

ВЫХОД

1
3.14.6-1-ARCH
2
/proc/24925/fd/pipe:[5851017]
3
#blank
4
#blank
5
#blank

решение1

/dev/fd/0является стандартным вводом текущего процесса; teeзаписывает свой ввод как в файл(ы), которые вы ему даете, так и в stdout. То же самое teeкасается чтения (пустой) строки, а затем записи этой строки как в stdout ( sed), так и в свой собственный ввод, где он считывает только что написанную строку, записывает ее в stdout и свой собственный ввод и т. д., создавая бесконечный цикл (пустых) строк*. Команда sedпросто печатает номер строки, а затем строку.

echo --> tee --> sed
      ^---+

* Если введено больше входных данных, чем просто echo, эта команда будет циклически обрабатывать входные данные, повторяя их снова и снова.

Примечание: OSX (BSD) не позволяет вам записывать в /dev/fd/0, поэтому вы не можете этого сделать.

Связанный контент