Shell

通過多個管道過濾 ping 輸出失敗

  • February 13, 2020

試圖僅從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 '^[^ ]*'

如果您點擊此連結,還有更多資訊和解決方法(解決方案?)

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