Bash

命令替換中的阻塞/非阻塞管道/重定向

  • August 11, 2017

我在 bash 中觀察到以下行為:

{ echo 'foo' ; sleep 10 ; }

-> 標準輸出“foo”立即出現,10 秒後命令完成(如預期)

{ echo 'foo' ; sleep 10 ; } > >(grep 'oo')

-> 標準輸出“foo”立即出現,10 秒後命令完成(如預期)

{ echo 'foo' ; sleep 10 ; } > >(grep 'oo' | grep 'oo')

-> 標準輸出“foo”在 10 秒後出現

{ echo 'foo' ; sleep 10 ; } > >(grep 'oo' >&2)

-> 10 秒後出現標準錯誤“foo”

為什麼命令替換中帶有單個 grep 的命令行會立即輸出其結果,而帶有管道和重定向的變體要等到睡眠結束?

你不需要那麼花哨;你可以觀察到同樣的效果

{ echo 'foo' ; sleep 10 ; } | grep oo | grep oo

或者

{ echo 'foo' ; sleep 10 ; } | grep oo | cat

或者

  • 打開兩個終端。轉到兩者中的相同目錄(例如,您的主目錄或/tmp)。
  • 在一個,做{ echo 'foo' ; sleep 10 ; } | grep oo > foo.out
  • 另一方面,ls -ld foo.out反复做。

您將看到該foo.out文件立即出現,但大小為 0 十秒鐘,之後變為 4 個字節長。

簡單地說:grep測試它的(標準)輸出是否是終端。如果是,它會盡快寫入輸出,因為它有輸出要寫入。如果不是,它會緩衝其輸出,並一次寫入N  個字節,其中N  通常為 512,但在某些實現中可能會有所不同。

引用自:https://unix.stackexchange.com/questions/385591