web-dev-qa-db-ja.com

自分のIPアドレスを取得してシェルスクリプトの変数に保存する方法

自分のIPアドレスを取得してシェルスクリプトの変数に保存するにはどうすればよいですか?

68
Tom Brito

Wlanやその他の代替インターフェースを考慮に入れる場合、それほど簡単ではありません。アドレスが必要なインターフェースがわかっている場合(たとえば、最初のイーサネットカードであるeth0)、これを使用できます。

ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"

つまり、ネットワーク構成情報を取得し、eth0を探し、その行と次の行を取得します(-A 1)、get only最後の行、2番目を取得します:で分割するときにその行の一部を、次にスペースで分割するときにその最初の部分を取得します。

31
l0b0

Ipv4アドレスを取得するための「最新のツール」の方法は、「ifconfig」ではなく「ip」を解析することであるため、次のようになります。

ip4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
ip6=$(/sbin/ip -o -6 addr list eth0 | awk '{print $4}' | cut -d/ -f1)

またはそのようなもの。

71
jsbillings

なぜ単純にIP=$(hostname -I)をしないのですか?

39
Andrei

インターフェイスのアドレスが必要な場合は、moreutilsをインストールするのが最も簡単な方法です。

anthony@Zia:~$ ifdata -pa br0
172.16.1.244

ifdataは、ifconfigの出力を解析したくなるすべての質問に答えます。

外部から見たIPアドレス(NATなどを超えたもの)を知りたい場合は、それを行うサービスがたくさんあります。 1つはかなり簡単です。

anthony@Zia:~$ curl ifconfig.me
173.167.51.137
27
derobert

IPv4アドレスとIPv6アドレスを取得し、メインインターフェイスがeth0(最近はem1より一般的 )であると想定しない場合は、次のことを試してください。

ips=$(ip -o addr show up primary scope global |
      while read -r num dev fam addr rest; do echo ${addr%/*}; done)
  • -oは、readgrepなどで処理するのが簡単な1行の出力形式を使用します。
  • upは、アクティブでないデバイスを除外します
  • scope globalは、127.0.0.1fe80::/64などのプライベート/ローカルアドレスを除外します
  • primary excludes temporary addresses (あなたが変化しないアドレスが欲しいと仮定して)
15
Mikel

私はジャークであるつもりはありませんが、実際にはrightの方法があり、これがそれです。 _ip route_の出力をトリミングして、ソースIPのみを取得します。到達しようとしているIPによって、「自分のIPアドレス」(OPの言葉)は異なります。公共のインターネットにアクセスすることを気にする場合は、Googleの8.8.8.8 DNSサーバーの使用がかなり標準的です。そう...

短い答えは:

_ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
_

詳細はこちら

internetに到達するために使用するIPが必要な場合は、これを使用します。

_pi@et3:~ $ ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
10.55.0.200
_

[〜#〜] vpn [〜#〜]で何かに到達するために使用するIPが必要な場合は、これを使用します。

_pi@et3:~ $ ip route get 172.31.0.100 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
172.29.0.9
_

この次のものは、実際には説明のためのものです。しかし、どのLinuxシステムでも機能するはずです。したがって、これを使用して、すべてのマシンが常に複数のIPアドレスを持っていることを実証できます。

myselfに到達するために使用するIPが必要な場合は、これを使用します。

_pi@et3:~ $ my_ip=$(getent hosts $(cat /etc/hostname) | awk '{print $1; exit}')
pi@et3:~ $ ip route get $my_ip | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
127.0.0.1
_

そのsedコマンドの詳細

最初に、UNIXツールを選択するときは、パイプの数が最も少ないツールを選択しようとすることを言います。したがって、一部の回答ではifconfigからgrepからsedからheadへのパイプが使用されますが、これが必要になることはほとんどありません。それを見るとき、それはあなたがほとんど経験のない人からアドバイスを取っているという赤い旗を上げるはずです。 「ソリューション」が間違っているわけではありません。しかし、おそらくいくつかの合理化を使用できます。

sedを選択したのは、awkの同じワークフローよりも簡潔であるためです。 (私は以下のawkの例を持っています。)他のツールはないと思いますが、これらの2つが適切でしょう。

sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'の機能を見てみましょう:

_sed            # the sed executable located via $PATH
-n             # no output unless explicitly requested
'              # begin the command space
/src/          # regex match the string 'src'
{              # begin a block of commands **
s/             # begin a substitution (match)
  .*src *      # match anything leading up to and including src and any number of spaces
  \([^ ]*\)    # define a group containing any number of non spaces
  .*           # match any trailing characters (which will begin with a space because of the previous rule).
/              # begin the substitution replacement
  \1           # reference the content in the first defined group
/              # end the substitution
p              # print (explicitly, remember) the result
;              # designate the end of the command
q              # quit
}              # end the block of commands
'              # end the command space

** all of which will be performed "on match"
  - otherwise only the first command to following the match would be performed "on match"
    - any other commands would be performed whether there was a match or not
_

以前は_sed -n '/src/{s/.*src *//p;q}'_を使用していましたが、一部のシステムではsrcフィールドの後に後続データがあるとコメント者が指摘しました。

Awkの使用

_ip route get 8.8.8.8 | \
    awk '{gsub(".*src",""); print $1; exit}'

# or

ip route get 8.8.8.8 | \
    awk '{for(i=1; i<NF; i++){if($i=="src"){i++; print $i; exit}}}'
_

私のネットワークの詳細

私のifconfigは、VPNに_tun0_、LANに_eth0_があることを示しています。

_pi@et3:~ $ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.55.0.200  netmask 255.255.252.0  broadcast 10.55.3.255
        inet6 fe80::71e6:5d7c:5b4b:fb25  prefixlen 64  scopeid 0x20<link>
        ether b8:27:eb:b2:96:84  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<Host>
        loop  txqueuelen 1  (Local Loopback)

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 172.29.0.9  netmask 255.255.255.255  destination 172.29.0.10
        inet6 fe80::3a8e:8195:b86c:c68c  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)

wlan0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether b8:27:eb:e7:c3:d1  txqueuelen 1000  (Ethernet)
_
9
Bruno Bronosky
ipa=$(ip route get 8.8.8.8| grep src| sed 's/.*src \(.*\)$/\1/g')

ipa=$(hostname -i|cut -f2 -d ' ')
8
fastrizwaan

自分のIPアドレスの意味に依存します。システムにはいくつかのサブネット(サブネットごとにいくつかの場合もある)にIPアドレスがあり、その一部はIPv4、一部はイーサネットアダプター、ループバックインターフェイス、VPNトンネル、ブリッジ、仮想インターフェイスなどのデバイスを使用するIPv6です。

別の特定のデバイスがコンピュータに到達するためのIPアドレスを意味します。つまり、どのサブネットであるか、およびどのバージョンのIPについて話しているのかを知る必要があります。また、NATがファイアウォール/ルーターによって実行されるため、インターフェースのIPアドレスは、リモートホストが送信元のコンピューターからの受信接続を認識するのと同じではない可能性があることに注意してください。

派手なソースルーティングまたはプロトコル/ポートルーティングごとに、特定のプロトコルを介して1つのリモートコンピューターと通信するために使用されるインターフェイスを見つけるのは難しい場合があります。その場合でも、そのインターフェイスのIPアドレスがコンピュータへの新しい接続を確立しようとしているリモートコンピュータから直接アドレス指定できます。

IPv4の場合(おそらくIPv6でも機能します)、特定のホストに到達するために使用されるインターフェースのIPアドレスを見つけるためにLinuxを含む多くのuniceで機能するトリックは、UDPソケットでconnect(2)を使用し、getsocknameを使用することです():

たとえば、私の自宅のコンピュータで:

Perl -MSocket -le 'socket(S, PF_INET, SOCK_DGRAM, getprotobyname("udp"));
connect(S, sockaddr_in(1, inet_aton("8.8.8.8")));
print inet_ntoa((sockaddr_in(getsockname(S)))[1]);'

私が8.8.8.8(GoogleのDNSサーバー)に到達するために経由するインターフェースのIPアドレスを見つけるために使用されます。これは、インターネットへのデフォルトルートのインターフェースのアドレスである「192.168.1.123」のようなものを返します。ただし、NAT自宅のブロードバンドルーターによって実行されるため、Googleは私のマシンからのDNSリクエストがプライベートなIPアドレスから送信されているとは認識しません。

uDPソケットのconnect()はパケットを送信しません(UDPはコネクションレスです)が、ルーティングテーブルをクエリしてソケットを準備します。

8

FreeBSDで使用できます

Dig +short `hostname -f`

これは、セットアップによっては、他の環境でも機能する場合があります。

2
Tigger

さまざまな名前のさまざまなインターフェイスがあると仮定but最初の非localhostと非ipv6が必要であることを試してみてください:

ip=`ip addr show |grep "inet " |grep -v 127.0.0. |head -1|cut -d" " -f6|cut -d/ -f1`
2
Nicolas

ipifconfigの代わりに)を使用する必要があります。これは最新であり、維持されており、おそらくスクリプトの目的で最も重要なことですが、一貫性のある解析可能な出力を生成します。以下は、いくつかの同様のアプローチです。

イーサネットインターフェイスのIPv4アドレスが必要な場合eth0

$ ip -4 -o addr show eth0 | awk '{print $4}'
192.168.1.166/24  

スクリプトとして:

$ INTFC=eth0  
$ MYIPV4=$(ip -4 -o addr show $INTFC | awk '{print $4}') 
$ echo $MYIPV4
192.168.1.166/24

上記で生成された出力は CIDR表記になります。 CIDR表記が不要な場合は、削除できます。

$ ip -4 -o addr show eth0 | awk '{print $4}' | cut -d "/" -f 1 
192.168.1.166  

IMHOが「最もエレガント」である別のオプションは、指定されたリモートホスト(この場合は8.8.8.8)に接続するために使用されるインターフェイスのIPv4アドレスを取得します。 この回答 の@gatoatigradoの礼儀:

$ ip route get 8.8.8.8 | awk '{ print $NF; exit }'
192.168.1.166

スクリプトとして:

$ RHOST=8.8.8.8  
$ MYIP=$(ip route get $RHOST | awk '{ print $NF; exit }')
$ echo $MYIP
192.168.1.166

これは、単一のインターフェースを持つホストで完全に機能しますが、複数のインターフェースやルート指定を持つホストでも機能します。

ipが私の推奨アプローチですが、この猫の皮を剥ぐ唯一の方法ではありません。より簡単で簡潔な方がよい場合は、hostnameを使用する別の方法を次に示します。

$ hostname --all-ip-addresses | awk '{print $1}'  

または、IPv6アドレスが必要な場合:

$ hostname --all-ip-addresses | awk '{print $2}'  
1
Seamus
myip=$(curl -kLs "http://api.ipify.org")

または

myip=$(wget -q "http://api.ipify.org" -O -)
1
Zibri

私はこのワンライナーを使用します:

IP=$(/sbin/ifconfig | grep -e "inet:" -e "addr:" | grep -v "inet6" | grep -v "127.0.0.1" | head -n 1 | awk '{print $2}' | cut -c6-)

ifconfig(広く利用可能)を使用し、localhostアドレスを取得せず、特定のインターフェイス名にバインドせず、IPv6を考慮せず、最初のネットワークインターフェイスのIPを取得しようとします利用可能です。

1

このスニペットは、デバイス名( 'eth0'など)のハードコーディングを回避し、ipではなくifconfigを使用します。

/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/'

ip addrの出力にリストされている最初のアクティブデバイスのIPを返します。マシンに応じて、これはipv4またはipv6アドレスになります。

それを変数に格納するには、次を使用します。

ip=$(/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/')
0
Philipp Claßen

プライマリパブリックIPが必要であると仮定した場合他の世界から見ると、それらのいずれかを試してください。

wget http://ipecho.net/plain -O - -q
curl http://icanhazip.com
curl http://ifconfig.me/ip
0
Putnik

有線NICで無線サーバーを起動するには、エイリアス内でこれを行う必要がありました。使った

ip addr | egrep -i "inet.+eth1" | awk -F[\ /] '{print $6}' | tr -d [:space:]
0
user208145

awk/sed/grepを使用するすべてのソリューションは、私の状況では過度に複雑で醜いように見えます...したがって、私はこの本当にシンプルなソリューションを思い付きましたが、いくつかの仮定、つまりLASTインターフェイスがあなたが使用しているものであるという仮定に注意してください興味がある。あなたがそれで大丈夫なら、これはかなりきれいです:

ifconfig | awk '/net / { x = $2 } END { print x }'

それ以外の場合は、いくつかの愚かなifステートメントを実行して、特定のプレフィックスまたはユーザーが持つ可能性のある基準をテストできます。

0
mad.meesh

これは最も堅牢または正しいソリューションではない可能性がありますが、他のほとんどのソリューションとは異なり、コマンドはLinuxとMac(BSD)の両方で機能します。

Host `hostname` | awk '{print $NF}'
0
wisbucky

一部のコマンドはcentos 6または7で動作し、以下のコマンドは両方で動作します。

#!/bin/sh

serverip=`/sbin/ifconfig eth0 | grep "inet" | awk '{print $2}' | awk 'NR==1' | cut -d':' -f2`

echo $serverip
0
lakshmikandan

デフォルトのインターフェースでIPアドレスを細かく設定する簡単なコマンド

ip route | grep src | awk '{print $NF; exit}'

すべてのUnix OSでテスト済み

0
M.S.Arun

ボックスのパブリックIPアドレス を探している場合は、以下を使用できます。

  • _Dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"_

_-4_や_-6_などの Dig(1) オプションを使用して、IPv4またはIPv6アドレスを具体的に検索できます。 Googleは、TXTタイプのレコードで回答を提供します。Digによって提示された場合、そのタイプは引用符で囲まれます。その後、tracerouteなどのユーティリティで変数を使用する場合は、 tr(1) のようなものを使用して、引用符を削除する必要があります。

他のオプションには_whoami.akamai.net_および_myip.opendns.com_が含まれ、これらはAおよびAAAAレコードで応答します(上記のGoogleの例のTXTではなく)。したがって、引用符を削除する必要はありません。

  • _Dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short_

  • _Dig -4 @resolver1.opendns.com -t any myip.opendns.com +short_

  • _Dig -6 @resolver1.opendns.com -t any myip.opendns.com +short_

上記のすべてのオプションを使用して変数を設定するサンプルスクリプトを次に示します。

_#!/bin/sh
IPANY="$(Dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
GOOGv4="$(Dig -4 @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
GOOGv6="$(Dig -6 @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \")"
AKAMv4="$(Dig -4 @ns1-1.akamaitech.net -t a whoami.akamai.net +short)"
CSCOv4="$(Dig -4 @resolver1.opendns.com -t a myip.opendns.com +short)"
CSCOv6="$(Dig -6 @resolver1.opendns.com -t aaaa myip.opendns.com +short)"
printf '$GOOG:\t%s\t%s\t%s\n' "${IPANY}" "${GOOGv4}" "${GOOGv6}"
printf '$AKAM:\t%s\n$CSCO:\t%s\t%s\n' "${AKAMv4}" "${CSCOv4}" "${CSCOv6}"
_

プライベートIPアドレス、またはボックスに割り当てられたすべてのIPアドレスのセットを探している場合は、 ifconfig (BSDおよびGNU/Linuxの場合)、_ip addr_(GNU/Linuxの場合)、 hostname (オプション_-i_および_-I_(GNU/Linuxの場合))および netstat は、何が起こっているかを確認します。

0
cnst