私は以下の関数を使用して外部スクリプトを増分しています。この主な目的は、ifconfig および ping テスト出力からいくつかのデータを返すことです。変数を使用して同じ関数内でそれらを設定して、他の「パイプ」を実行し、他の情報と再度連結しようとしています。しかし、この動作が発生しました。基本的に、私がしようとしていることは次のとおりです。
> for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | a=`echo $i-$(cut -d,
-f3)` | echo $a; done
4
4
4
4
ご覧のとおり、各反復で数値 4 が返されます。
変数の属性を削除すると、最初に変数 'a' に設定することを期待していた出力が得られます。
> for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | echo $i-$(cut -d, -f3); done
10.0.2.15- 0% packet loss
192.168.0.2- 0% packet loss
10.0.2.100- 0% packet loss
127.0.0.1- 0% packet loss
- 最初の関数コード実行で出力として数字 4 が返されるのはなぜですか?
- 同じ関数内で変数を設定し、いくつかのパイプラインの後にそれを再度エコーするにはどうすればよいでしょうか? それは可能ですか?
よろしくお願いします !
答え1
for i in $(...) ; do ... | a=`...` | echo $a; done
最初の関数コード実行で出力として数字 4 が返されるのはなぜですか?
a=`...`
と はecho $a
異なるサブシェル/サブプロセスで実行されるためです。 はどのシェルでもa=1; a=3 | echo $a
出力されます1
。サブシェルから親に変数を渡す方法はありません。
同じ関数内で変数を設定し、いくつかのパイプラインの後にそれを再度エコーするにはどうすればよいでしょうか? それは可能ですか?
いいえ。パイプラインの前のメイン スクリプトで設定しない限りは。
答え2
パイプラインの最後の部分を で再構成すれば、sed
望みどおりsed
の結果が得られると思います。スクリプトは標準入力全体を の値に置き換え、それに$i
続いて出力-
の 3 番目のフィールドping
(stdin から) の値を返します。たとえば、
$ for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f3 | cut -d: -f2); do \
ping -c1 $i | grep packet | cut -d, -f3 | sed "s/\(.*\)/$i - \\1/"; \
done
123.145.167.189 - 0% packet loss
127.0.0.1 - 0% packet loss