Pipe
為什麼在某些情況下我無法重定向輸出
例如
# this line should output ssh banner nc localhost 22 # this line should output the same string expect the replacements nc localhost 22|sed 's/SSH/XXX/g' nc localhost 22 > foo # after killing the process, I can see the banner in file `foo` nc localhost 22|sed 's/SSH/XXX/g' > foo # however I see nothing when sed is used
如前所述,如果我使用
sed
管道nc
傳輸 ’ 的輸出,則sed
’ 的輸出無法重定向到文件。而且我還嘗試了其他命令來管道結果,例如
grep
,tr
,相同的結果。但是,
cat
可以將結果通過管道傳輸到文件中。奇怪的..nc localhost 22|cat > foo
那麼為什麼會這樣呢?
cat
在這種情況下,和其他命令有什麼區別?如何使sed
輸出重定向到文件cat
?
$ 貓 | sed -e 's/foo/bar/' > output.txt 富 ^C $ 貓輸出.txt *[沒有什麼]*
但:
$ 貓 | sed -e 's/foo/bar/' > output.txt 富 *^D* $ 貓輸出.txt 酒吧
寫入文件——但不寫入終端——通常由 C 庫(stdio 函式)緩衝到幾千字節的塊。如果您按 Ctrl-C 來終止管道,
sed
則在其終止之前將沒有時間寫出緩衝區,因此生成的輸出文件為空。(你可以說這是 C 庫中的一個錯誤,它沒有擷取終止信號,但它確實如此。)Plain
cat
可能不使用 stdio,因為它不處理像線條這樣複雜的東西。類似的東西cat -n
可能會有所不同,也可能不會。您可以安排這樣您就不需要使用 Ctrl-C 來終止管道,而是讓它自己完成。至少在 my 中
nc
,該-qN
選項告訴它在標準輸入關閉後N秒後退出,例如:$ printf '' | nc -q0 localhost 22 | sed 's/SSH/FOO/' > output.txt $ cat output.txt FOO-2.0-OpenSSH_7.4p1 Debian-10+deb9u7
或者,至少有幾種方法可以關閉緩衝,請參閱例如 關閉管道中的緩沖和
unbuffer
或stdbuf
以刪除標準輸出緩衝?GNU sed 也有
-u
/--unbuffered
開關從輸入文件中載入最少量的數據並更頻繁地刷新輸出緩衝區