web-dev-qa-db-ja.com

IPアドレスを抽出するLinux bashスクリプト

Debian 7.3で大きなスクリプトを作成したい(翻訳されたものや、はるかに新しいユーザーフレンドリーな環境のようなもの)。私は問題があります。コマンドから得られる情報の一部のみを使用します。たとえば、私のifconfigは次のようになります。

eth0      Link encap:Ethernet  HWaddr 08:00:27:a3:e3:b0  
          inet addr:192.168.1.103  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fea3:e3b0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1904 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2002 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1309425 (1.2 MiB)  T

IPアドレスのみを行に表示したい:echo "Your IP address is:(IP_ADDRESS)"。私が取得したい情報をストリームで検索するために、そのようなことを行うことができるコマンドはありますか? grepsedについて知っていますが、私は彼らとはあまり良くありません。

編集:まず、この問題で私を助けてくれてありがとうと言って、今ではもっと多くを知っています。第二に、プロジェクトは進行中です。誰かがそれに興味があるなら、ちょうど私に午後。

35
user3232381

IPアドレスを取得するには:

echo `ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`

これにより、eth0のIPアドレスが得られます。

編集:Ubuntuの最近のバージョンでインターフェースの名前が変更されたため、これはもう機能しません。代わりに、これを使用することができます:

hostname --all-ip-addressesまたはhostname -I、これは同じことを行います(ホストのすべてのIPアドレスを提供します)。

35
Marco Hegenberg

目標がIPアドレスを見つけることである場合インターネットの方向に接続されている場合、これは良い解決策です。


更新!!! Linuxの新しいバージョンでは、次の行で詳細情報を取得できます。

ip route get 8.8.8.8
8.8.8.8 via 10.36.15.1 dev ens160 src 10.36.15.150 uid 1002
    cache

iPを取得するには、srcの後にIPを見つける必要があります

ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}'
10.36.15.150

インターフェース名が好きなら

ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}'
ens192

ip routeは接続を開きません。8.8.8.8に到達するために必要なルートを表示するだけです。 8.8.8.8はGoogleのDNSです。

これを変数に保存する場合は、次のようにします。

my_ip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

my_interface=$(ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}')

他のソリューションが失敗する理由:

ifconfig eth0

  • 使用しているインターフェイスに別の名前(eno1、wifi、venet0など)がある場合
  • 複数のインターフェイスがある場合
  • IP接続方向は、複数のIFのリストの最初ではありません

Hostname -I

  • 127.0.1.1のみが取得される場合があります
  • すべてのシステムで動作するわけではありません。
81
Jotne

IPのスペース区切りリストを取得する場合は、hostnameコマンドと--all-ip-addresses(短い-I)フラグを使用できます。

hostname -I

ここで説明されているように: bash変数にIPアドレスを入力します。より良い方法はありますか

35
user000001
ip -4 addr show eth0 | grep -oP "(?<=inet ).*(?=/)"
7
John

すべての場合(特に複数のNICがある場合)に当てはまるとは限りません。

hostname -I | awk '{ print $1 }'
5
Pavel
  /sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'
4
ip route get 8.8.8.8| grep src| sed 's/.*src \(.*\)$/\1/g'
4
fastrizwaan

好きなものを選んでください:

$ cat file
eth0      Link encap:Ethernet  HWaddr 08:00:27:a3:e3:b0
          inet addr:192.168.1.103  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fea3:e3b0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1904 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2002 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1309425 (1.2 MiB)  T

$ awk 'sub(/inet addr:/,""){print $1}' file
192.168.1.103

$ awk -F'[ :]+' '/inet addr/{print $4}' file
192.168.1.103
4
Ed Morton

サーバーでのアップグレードのトラブルシューティングに少し時間を費やしただけなので、ご注意ください。結局、(数年前に)動的に追加されたインターフェイス(たとえばeth0:1)が存在するかどうかを確認するテストを実装し、存在する場合は、特定のproggisをeth0の「メイン」IPにバインドしました。基本的に、これは「ifconfig | grep ... | sed ...」ソリューションのバリエーションでした(さらに「eth0:」の存在をチェックします)。
アップグレードにより新しいネットツールが導入され、それに伴い出力がわずかに変更されました。

古いifconfig:

eth0      Link encap:Ethernet  HWaddr 42:01:0A:F0:B0:1D
          inet addr:10.240.176.29  Bcast:10.240.176.29  Mask:255.255.255.255
          UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
          ...<SNIP>

一方、新しいバージョンでは次のように表示されます。

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1460
      inet 10.240.212.165  netmask 255.255.255.255  broadcast 10.240.212.165
      ...<SNIP>

「eth0:」および「inet addr:」検索のハントをレンダリングします(「em0」、「br0」、または「wlan0」と呼ばれるインターフェースを気にしないでください)。確かに 'inet'(または 'inet6')を確認し、addr:部分をオプションにすることもできますが、近くを見ると、多かれ少なかれすべてが変更されていることがわかります。'Mask 'は' netmask 'です。 。

「ip route ...」の提案はかなり気の利いたものです。

_MyIP="$( ip route get 8.8.8.8 | awk 'NR==1 {print $NF}' )"
if [ "A$_MyIP" == "A" ]
then
    _MyIPs="$( hostname -I )"
    for _MyIP in "$_MyIPs"
    do
        echo "Found IP: \"$_MyIP\""
    done
else
    echo "Found IP: $_MyIP"
fi

まあ、とにかくそのような何か。提案されたすべてのソリューションは失敗する状況があるように見えるので、可能性のあるエッジケースを確認してください-ethなし、複数のeth&lo、「hostname -i」が失敗するとき... 2番目に良い。

乾杯 'n'ビール!

2
Kevin

以前のip route ...ソリューションの1つにわずかな変更を加えたため、grepが不要になりました。

ip route get 8.8.8.8 | sed -n 's|^.*src \(.*\)$|\1|gp'
0
Doug R.

私の意見では、必要なものを達成するための最も簡単でエレガントな方法は次のとおりです。

ip route get 8.8.8.8 | tr -s ' ' | cut -d' ' -f7

ip route get [Host]-リモートホストに到達するために使用されるゲートウェイを提供します。例:

8.8.8.8 via 192.168.0.1 dev enp0s3  src 192.168.0.109

tr -s ' '-余分なスペースを削除します。現在、統一性があります。例:

8.8.8.8 via 192.168.0.1 dev enp0s3 src 192.168.0.109

cut -d' ' -f7-文字列を ''スペースで区切られたフィールドに切り捨ててから、フィールド#7を選択します。例:

192.168.0.109
0
leonarth
awk '/inet addr:/{gsub(/^.{5}/,"",$2); print $2}' file
192.168.1.103
0
Claes Wikner