Shell
通過多個管道過濾 ping 輸出失敗
試圖僅從
ping
輸出中擷取數據包返回時間,我發出$ ping 192.168.0.1 | grep -o '[^ =]* ms'
它起作用了,顯示每個數據包到達的時間。由於我也想擺脫時間單位,因此認為這就足夠了:
$ ping 192.168.0.1 | grep -o '[^ =]* ms' | grep -o '^[^ ]*'
但是,令我驚訝的是,它掛起,沒有顯示輸出。
echo
但是,用輸出中的範例行替換第一個命令ping
可以按預期工作(它輸出5.07
):$ echo '64 bytes from 192.168.0.1: icmp_seq=10 ttl=64 time=5.07 ms' | grep -o '[^ =]* ms' | grep -o '^[^ ]*'
我找到了其他方法來獲取沒有毫秒單位的時間,但仍然:
ping
命令有什麼問題?為什麼通過一個管道可以,但不能通過兩個?PS:下面的這些也失敗了,而他們的
echo
版本成功了,所以問題不在於grep
$ ping 192.168.0.1 | grep -o '[^ =]* ms' | sed 's_ ms__' $ ping 192.168.0.1 | grep -o '[^ =]* ms' | cut -f 1 -d ' ' $ ping 192.168.0.1 | cut -f 7 -d ' ' | cut -f 2 -d '='
明確的答案是行緩衝。
ping -c 3
您可以使用而不是 just來展示這一點ping
,其中所有輸出僅在第一個命令完成時產生。作為 GNU 的一種解決方法,
grep
您可以將兩個過濾器減少到一個ping 192.168.0.1 | grep -oP '[[:digit:].]+(?= ms)'
或者,如果您真的想使用兩個過濾器,
grep --line-buffered ...
或者stdbuf -oL grep ...
將適合您。
我認為您的問題是由您的外殼的行緩衝引起的。
如果您讓命令執行足夠長的時間,您應該會看到一些輸出。
或者只是限制這樣的 ping 數量:
$ ping -c4 192.168.0.1 | grep -o '[^ =]* ms' | grep -o '^[^ ]*'
如果您點擊此連結,還有更多資訊和解決方法(解決方案?)