
Я просто игрался в терминале и сделал следующее:
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
, поэтому вы не можете этого сделать.