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
コマンドに何が問題ですか? 1つのパイプを通っては大丈夫ですが、2つのパイプを通っては大丈夫ではありません。
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 '='
答え1
確かな答えはラインバッファ。ping -c 3
を使用する代わりに、ping
最初のコマンドが完了したときにのみすべての出力が生成されることを使用してこれを実証できます。
GNUの回避策として、grep
2つのフィルタを1つに減らすことができます
ping 192.168.0.1 | grep -oP '[[:digit:].]+(?= ms)'
あるいは、本当に両方のフィルタを使用したい場合は、grep --line-buffered ...
どちらかstdbuf -oL grep ...
が適切です。
答え2
あなたの問題はシェルのラインバッファリングによって引き起こされたようです。
コマンドを十分に長時間実行すると、いくつかの出力が表示されます。
または、次のようにping数を制限します。
$ ping -c4 192.168.0.1 | grep -o '[^ =]* ms' | grep -o '^[^ ]*'
これによれば、より多くの情報と解決策(ソリューション?)があります。協会