![無底T卹?](https://rvso.com/image/38314/%E7%84%A1%E5%BA%95T%E5%8D%B9%EF%BC%9F.png)
我只是在終端機裡玩,我這樣做了:
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
將其輸入寫入您提供的文件和標準輸出。讀取tee
一個(空白)行,然後將該行寫入 stdout ( sed
) 及其自己的輸入,其中它讀取剛剛寫入的行,將其寫入stdout 及其自己的輸入等,從而創建一個無限循環(空)行*。此sed
指令僅列印行號,然後列印行號。
echo --> tee --> sed
^---+
* 當提供的輸入不僅僅是一個簡單的輸入時echo
,此命令將循環輸入,一遍又一遍地重複。
注意:OSX (BSD) 不允許您寫入/dev/fd/0
,因此您不能執行此操作。