whileループから放出されたすべての行をシェルの単一変数にどのように格納できますか?

whileループから放出されたすべての行をシェルの単一変数にどのように格納できますか?

私が知る限り、シェルのwhileループはサブシェルで実行されるので、ループの外側の変数を変更することはできません。

シェルスクリプトを作成していますが、マシンのすべての内部IPを変数に保存したいので、forループを使用して変数を処理し、iptablesを使用して1つずつフィルタリングします。

次のコードを書くことができます。

ip route show default | awk '{ print $5 }' | while read line; do
  ip address show dev ${line} scope global | awk '/inet / {sub(/\/.*/, "", $2); print $2}' | while read line; do
    echo "${line} "
  done
done

出力:

10.17.0.49 
192.168.1.4

私の質問は次のとおりです

whileループから放出されたこれらすべての行を単一の変数にどのように格納できますか(whileループ変数は揮発性なので)。

ベストアンサー1

基本パスに含まれるインターフェイスのすべてのグローバルスコープローカルアドレスを印刷するために、より安定した方法でプログラム的に処理できるJSON形式を使用します。

perl -MJSON -le '
  $default_routes = decode_json(qx(ip -j route show default));
  for (@$default_routes) {$devs{$_->{dev}} = 1}
  $addresses = decode_json(qx(ip -j address show));
  for (@$addresses) {
    if ($devs{$_->{ifname}}) {
      for (@{$_->{addr_info}}) {
        print $_->{local} if $_->{scope} eq "global";
      }
    }
  }'

または同じものを使用してくださいjq

ip -j address show |
  jq -r --argjson devs "$(
      ip -j route show default|jq 'map({"key":.dev})|from_entries'
    )" '.[]|select(.ifname|in($devs)).addr_info[]|
      select(.scope == "global").local'

(JSON出力をサポートするには比較的新しいバージョンが必要ですiproute2)。

この項目(またはより一般的にはコマンドの各出力行)を配列に入れるには、次のようにbashします。

readarray -t array < <(
  that-command above
)

目標がデフォルトルートを介して送信されたパケットが取得できる送信元IPアドレスを取得することである場合は、例を参照してください。私の答え到着私のIPアドレスをどのように取得し、それをシェルスクリプトの変数に保存しますか?

おすすめ記事