自分のIPアドレスを取得して、シェルスクリプトの変数に保存するにはどうすればよいですか?
自分のIPアドレスを取得して、シェルスクリプトの変数に保存するにはどうすればよいですか?
回答:
wlanや他の代替インターフェースを考慮したい場合、それはそれほど簡単ではありません。アドレスが必要なインターフェイスがわかっている場合(たとえば、eth0、最初のイーサネットカード)、これを使用できます。
ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
つまり、ネットワーク構成情報をeth0
取得し、その行と次の行(-A 1
)を探し、最後の行のみを取得し、で分割するときにその行の2番目の部分を:
取得し、次に分割するときにその行の最初の部分を取得しますスペースで。
grep
コードに「eth0:」を含むインターフェイスを無視するための追加を追加しました。これは、期待どおりに機能するようになりました(「eth0」IPアドレスのみを提供し、サブインターフェース(eth0:0、eth0:1など)は提供しません):ip="$(ifconfig | grep -v 'eth0:' | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
ifconfig eth0
ip address
代わりに
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)
またはそのようなもの。
ip
私が使用したすべてのRed HatおよびFedoraディストリビューションで利用可能です。 ip
iproute2パッケージの一部です(linuxfoundation.org/collaborate/workgroups/networking/iproute2)。 ifconfig
そしてroute
彼らは、特にスクリプトで、多くの人々によって使用され続けるが、おそらく、廃止されました。 ip
私の意見では、はるかに解析可能です。
ip
私が見たすべてのDebianおよびDebianベースのディストリビューションでも利用可能です。重要としてマークされているiprouteパッケージの一部です。
ip
デフォルトで多くのディストリビューションであるiproute2パッケージの一部です。最も良いリポジトリです。 en.wikipedia.org/wiki/Iproute2
/sbin/ip
代わりにip
?
awk
とはcut
私に穏やかに面白いです、ここでは実際には良くないかもしれない可能な代替です:ip -o -4 addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'
なぜ単純にしないのIP=$(hostname -I)
ですか?
hostname -i
ちょうど私127.0.0.1
をhostname -I
与える、私に正しいIPアドレスを与える...-
-i Display the network address(es) of the host name. Note that this works only if the host name can be resolved. Avoid using this option; use hostname --all-ip-addresses
/etc/hosts
対応するIPアドレスと一緒に、
-I
FreeBSD上で、しかし、あなたは使用することができますdig +short `hostname -f`
インターフェイスのアドレスが必要な場合、最も簡単な方法は、moreutilsをインストールすることです。
anthony@Zia:~$ ifdata -pa br0
172.16.1.244
ifdata
ifconfig
出力を解析したいと思うすべての質問にほぼ答えます。
IPアドレスを外部から見たときに(NATなどを超えて)見つけたい場合は、それを行うサービスがたくさんあります。1つはかなり簡単です。
anthony@Zia:~$ curl ifconfig.me
173.167.51.137
ifdata
追加していただけたらうれしいですiproute2
。呼ばれるかもしれない新しいバイナリipdata
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)
-4
/ -6
を渡して、アドレスタイプをフィルタリングできます。他のインターフェイスパラメータも簡単に取得できます。個人的に、私はwhileループ嫌いと私は好むgrep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
自分のIPアドレスの意味に依存します。システムには複数のサブネット(サブネットごとに複数)にIPアドレスがあり、その一部はIPv4、一部はイーサネットアダプター、ループバックインターフェイス、VPNトンネル、ブリッジ、仮想インターフェイスなどのデバイスを使用するIPv6 ...
つまり、特定の別のデバイスがコンピューターに到達するためのIPアドレスを意味します。つまり、どのサブネットであり、どのバージョンのIPについて話しているのかを知る必要があります。また、ファイアウォール/ルーターによって実行されるNATのために、インターフェイスのIPアドレスは、リモートホストがコンピューターからの着信接続を受信するのと同じでない場合があることに注意してください。
派手なソースルーティングがある場合、またはプロトコル/ポートルーティングごとにある場合、特定のプロトコルを介して1つのリモートコンピューターと通信するために使用されるインターフェイスを見つけることは困難であり、その場合でもそのインターフェイスのIPアドレスがコンピューターへの新しい接続を確立したいリモートコンピューターによって直接アドレス指定可能。
IPv4の場合(おそらくIPv6でも動作します)、Linuxを含む多くの大学で、特定のホストに到達するために使用されるインターフェースのIPアドレスを見つけるためのトリックは、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はプライベートIPアドレスから送信されたマシンからのDNS要求を認識しません。
UDPソケットのconnect()はパケットを送信しません(UDPはコネクションレスです)が、ルーティングテーブルを照会してソケットを準備します。
ipa=$(ip route get 8.8.8.8| grep src| sed 's/.*src \(.*\)$/\1/g')
ipa=$(hostname -i|cut -f2 -d ' ')
-I
代わりに、-i
ループバック住所がを無視したいとより良いされて、最終的なコマンドは次のようになりipa=$(hostname -I|cut -f1 -d ' ')
grep
十分でない場合は、他のものにパイプしないでください。ただ、何か他のもの(使用sed
、awk
など)。
意地悪をするつもりはありませんが、本当に正しい方法があり、これがそれです。の出力をトリミングして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}'
私がインターネットに到達するために使用する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アドレスを持っていることを示すことができます。
私が自分自身に到達するために使用する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
to 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
フィールドの後にデータが続くことをコメント者が指摘しました。
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
ショーはtun0
、VPNとeth0
LANのために持っています。
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)
ip route get 8.8.8.8 | sed -n '/src/{s/.*src *//p;q}'
私にくれた10.1.2.3 uid 1002
。したがって| awk '{print $1}'
、IPアドレスのみを保持するためにappendを追加します。
FreeBSDでは次を使用できます
dig +short `hostname -f`
これは他の環境で機能する場合がありますが、設定によって異なります。
/etc/resolv.conf
、ネットワークルーターがローカルホスト名をどのように処理するかによって異なります。テストして機能する場合は、環境でこれを使用しても問題ありません。しかし、そうすれば、これを共有すると他の問題を引き起こす「脆弱な」システムを構築していることになります。注意して使用してください。
私はこのワンライナーを使用します:
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を取得しようとします。
使用する必要がありますip
(の代わりにifconfig
)現在、維持されており、おそらく最も重要なのはスクリプトの目的であり、一貫した解析可能な出力を生成します。以下は、いくつかの同様のアプローチです。
イーサネットインターフェイスの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}'
有線NICで無線サーバーを起動するには、エイリアス内でこれを行う必要がありました。使った
ip addr | egrep -i "inet.+eth1" | awk -F[\ /] '{print $6}' | tr -d [:space:]
egrep
減価償却されます。grep -E
代わりに使用してください。
一部のコマンドはcentos 6または7で機能し、以下のコマンドは両方で機能します。
#!/bin/sh
serverip=`/sbin/ifconfig eth0 | grep "inet" | awk '{print $2}' | awk 'NR==1' | cut -d':' -f2`
echo $serverip
grep | awk | awk
。行を次のように短縮できます/sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } '
このスニペットは、デバイス名(「eth0」など)のハードコーディングを回避しip
、ifconfig
次の代わりに使用します:
/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'
の出力にリストされている最初のアクティブなデバイスのIPを返しますip addr
。マシンに応じて、これはipv4またはipv6アドレスになります。
変数に保存するには、次を使用します。
ip=$(/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
ボックスのパブリックIPアドレスを探している場合は、次を使用できます。
dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"
またはなどのdig(1)
オプションを使用して、特にIPv4またはIPv6アドレスを検索できます。Googleは、タイプのレコードで回答を提供します。その後、変数をなどのユーティリティで使用する場合は、tr(1)などを使用して、上記の引用符を削除する必要があります。-4
-6
TXT
dig
traceroute
他のオプションには、whoami.akamai.net
とが含まれmyip.opendns.com
、で応答しA
、AAAA
記録します(TXT
上記のGoogleの例ではなく)ので、引用符を削除する必要はありません。
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
何が起こっているかを確認します。
hostname -I >> file_name
これはあなたが望むすべてを行います
hostname: invalid option -- 'l'
...