説明:
小さなbashスクリプトがあり、anyLinuxコマンドを実行するだけです(例:ifconfig
)
ifconfigの一般的な出力は次のようになります。
eth0 Link encap:Ethernet HWaddr 30:F7:0D:6D:34:CA
inet addr:10.106.145.12 Bcast:10.106.145.255 Mask:255.255.255.0
inet6 addr: fe80::32f7:dff:fe6d:34ca/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1104666 errors:0 dropped:0 overruns:0 frame:0
TX packets:2171 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:444437904 (423.8 MiB) TX bytes:238380 (232.7 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.255.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:15900 errors:0 dropped:0 overruns:0 frame:0
TX packets:15900 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:467306 (456.3 KiB) TX bytes:467306 (456.3 KiB)
これで、ほとんどの人は通常、entire出力をファイル/変数に格納し、それに基づいて解析します。しかし、とにかく出力の固有の部分を複数の変数(たとえばbash変数${IPETH0}
を呼び出してIPアドレス10.106.145.12
をeth0から送信し、${IPLO}
を呼び出してIPアドレス127.0.0.1
をlo上記の例ではifconfigコマンドを2回実行せずに)。
teeコマンドが入力に対して行うことのようなものですが、outputに対してこれを実行して、出力を2またはmore変数を一度に。何か案は?
答えを得ました:
$ read IPETH0 IPLO <<< $(ifconfig | awk '/inet[[:space:]]/ { print $2 }' | cut -d ':' -f 2)
$ echo "${IPETH0}"
192.168.23.2
$ echo "${IPLO}"
127.0.0.1
これは、eth0
およびlo
インターフェースの順序を想定していますが、基本的な考え方を示しています。
awk
これは、awk
関数を使用してsplit
で排他的に実行できます。
$ read IPETH0 IPLO <<< $(ifconfig | awk '/inet[[:space:]]/ { split($2,a,":"); print a[2]}')
コマンドのリターンのどの部分を保存したいか、コマンドごとに知っていると思います。
あなたの例では、これは単語番号7と47になります。
次のようにします(コマンドifconfig
の前後のティックに注意してください)。
array=(`ifconfig`)
この配列のすべての要素を表示:
echo ${array[@]}
eth0 Link encap:Ethernet HWaddr 30:F7:0D:6D:34:CA inet addr:10.106.145.12 Bcast:10.106.145.255 Mask:255.255.255.0 inet6 addr: fe80::32f7:dff:fe6d:34ca/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1104666 errors:0 dropped:0 overruns:0 frame:0 TX packets:2171 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:444437904 (423.8 MiB) TX bytes:238380 (232.7 KiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.255.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:15900 errors:0 dropped:0 overruns:0 frame:0 TX packets:15900 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:467306 (456.3 KiB) TX bytes:467306 (456.3 KiB)
特定の単語を表示:
echo ${array[6]} ${array[46]}
addr:10.106.145.12 addr:127.0.0.1
結果をsedにパイプして、IPアドレスのみを抽出します。
echo ${array[6]} ${array[46]} | sed 's/addr://g'
10.106.145.12 127.0.0.1
ここで「読み取り」を使用してArpithの気の利いたアプローチを使用すると、柔軟な答えになります。
read IPETH0 IPLO <<< $(echo ${array[6]} ${array[46]} |\
sed 's/addr://g')
echo $IPETH0 $IPLO
10.106.145.12 127.0.0.1
配列要素は0から数えられることに注意してください。したがって、Word番号7は「$ {array [6]}」と呼ばれます。
配列のインデックスは正の整数です。したがって、シェルスクリプトであらゆる種類の計算を実行して、特定の単語(範囲やforループなど)を選択できます...
移植可能なスクリプトを作成するには、これらの数値を含む一種のテーブルを保持する必要があります。私のシステム(BSD)では、IPアドレスはLinuxの番号7と47ではなく、番号17と49になります。また、結果の文字列は異なって見えます(ローカルとArpithのグローバルIDアドレスに関係なく):
echo ${array2[16]}
192.168.0.103
echo ${array2[48]}
127.0.0.1
slmの「純粋なawk」アプローチ(下記参照)は、私のBSDシステムでは失敗します。 「ifconfig」コマンドが「127.0.0.1」とArpithの「addr:127.0.0.1」を出力するため、配列への関数の分割は機能しません...
read IPETH0 IPLO <<< $(ifconfig |\
awk '/inet[[:space:]]/ { split($2,a,":"); print a[2]}')
HTH
バーニー
これを行う通常の方法は、たとえばawk
にbash
コードを生成させ、それをbash
で解釈させることです。
お気に入り:
eval "$(
ifconfig | awk -F '[: ]+' '
/^[^[:blank:]]/ {iface=$1}
/inet addr:/ {ip[iface]=$4}
END {for (i in ip) print "IP" toupper(i) "=" ip[i]}')"
[〜#〜] awk [〜#〜]:
/sbin/ifconfig | awk -F':' 'NR==2{split($2,a," "); print a[1]}'
[〜#〜] sed [〜#〜]:
ip -f inet addr show dev eth0 | sed -n 's/^ *inet *\([.0-9]*\).*/\1/p'
OR
ifconfig eth0 | sed -n 's/^ *inet addr:*\([.0-9]*\).*/\1/p'
[〜#〜] grep [〜#〜]:
ifconfig eth0|grep -Po 't addr:\K[\d.]+'
@Stephane Chazelasに感謝