127.0.0.1以外のローカルホストのプライマリ(最初の)IPアドレスを返すコマンドラインソリューションを探しています
このソリューションは、少なくともLinux(DebianおよびRedHat)およびOS X 10.7以降で機能します。
私はifconfig
両方で利用できることを知っていますが、その出力はこれらのプラットフォーム間でそれほど一貫していません。
curl -4 ifconfig.co
。外部IP4アドレスで応答します。
127.0.0.1以外のローカルホストのプライマリ(最初の)IPアドレスを返すコマンドラインソリューションを探しています
このソリューションは、少なくともLinux(DebianおよびRedHat)およびOS X 10.7以降で機能します。
私はifconfig
両方で利用できることを知っていますが、その出力はこれらのプラットフォーム間でそれほど一貫していません。
curl -4 ifconfig.co
。外部IP4アドレスで応答します。
回答:
grep
からIPアドレスをフィルタリングするために使用しますifconfig
:
ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'
またはsed
:
ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'
wlan0、eth0などの特定のインターフェースのみに関心がある場合:
ifconfig wlan0 | ...
でコマンドをエイリアス化して、たとえば呼び出される独自のコマンド.bashrc
を作成できますmyip
。
alias myip="ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'"
より簡単な方法はhostname -I
(hostname -i
古いバージョンの場合hostname
はコメントを参照)です。ただし、これはLinuxでのみ可能です。
-E
GNUスタイルの-r
オプションではなく、Extended RE のオプションを使用することにも注意してください。
-E
いることを知りませんでした。最近のバージョンのFreeBSDには、スクリプトの移植性を容易-r
に-E
するためのオプションがオプションとして追加されていますが、更新はまだOSXに引き継がれていません。OSXが何年にもわたって数回FreeBSDソースコードをドープしてきたため、どちらが正確かはわかりません。の使用はのオプションに-E
匹敵するように意図されていたと思います。なぜGNUの人々が代わりに選択したのかはわかりません。grep
-E
-r
-E
移植性を確実にするために使用するように回答を変更しました。これは更新される--help
と思いますman pages
。それにより、別の質問で以前に少し混乱を引き起こしました-E
以下はLinuxでは機能しますが、OSXでは機能しません。
これはDNSにまったく依存しておらず、/etc/hosts
正しく設定されていなくても機能します(の1
省略形です1.0.0.0
):
ip route get 1 | awk '{print $NF;exit}'
または、明白にawk
する8.8.8.8
ために、GoogleのパブリックDNSを避けて使用します。
ip route get 8.8.8.8 | head -1 | cut -d' ' -f8
信頼性の低い方法:(下のコメントを参照)
hostname -I | cut -d' ' -f1
hostname -I
は信頼できません。これは、(ドキュメントによると)アドレスの順序について想定できないためです。したがって、これは内部ネットワーク(仮想マシンが存在するネットワークなど)である可能性があります。他の方法は良いようです。
ip route get 1 | awk '{print $(NF-2);exit}'
は、出力にuidが追加されると機能します
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
Linuxマシン(OS Xではない)の場合:
hostname --ip-address
hostname -i
同等の短い形式です
hostname
。少なくともGNU Coreutilsバージョン8.26 では機能しません。
hostname -i
は、ローカルIPのみをhostname -I
提供し、他のすべてのIP を提供します
Linux上
hostname -I
macOS
ipconfig getifaddr en0
hostname -I
(参照信頼できないために、複数のアドレスを返すことができmanページを)、私にとってそれだけ返し、あなたが望んでいます、。hostname
192.168.1.X
hostname -i
低Iで
-i
フラグのマンページには次のように書かれていますAvoid using this option; use hostname -I instead
。
$ ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p'
192.168.8.16
正しいクエリネットワーク情報への道は、使用していますip
:
-o
1行出力route get to
宛先への実際のカーネルルートを取得する8.8.8.8
Google IP、ただし到達したい実際のIPを使用可能例:ip
出力:
8.8.8.8 via 192.168.8.254 dev enp0s25 src 192.168.8.16 uid 1000 \ cache
src
IP を抽出するにsed
は、最も正規表現であり、正規表現サポートと最も互換性があります。
-n
デフォルトでは出力なし's/pattern/replacement/p'
パターンに一致し、置換のみを印刷.*src \([0-9.]\+\).*
カーネルが使用するsrc IPに一致し、到達する 8.8.8.8
例:最終出力:
192.168.8.16
上記の回答は、最近のマシン(Gentoo 2018)では機能しないため、どれも私にとって十分ではないと思います。
上記の回答で見つけた問題:
ifconfig
は非推奨であり、たとえば、複数のIPをリストしないでください。awk
sedがより適切に処理できる単純なタスクの使用。ip route get 1
不明確であり、実際には ip route get to 1.0.0.0
hostname
コマンドの使用。-I
すべてのアプライアンスにオプションがなく127.0.0.1
、私の場合は戻ります。多くのインターフェイスと各インターフェイスに多くのIPが構成されているより強力な構成のために、に基づいて正しいインターフェイスと IP を見つけるための純粋なbashスクリプト(に基づいていない127.0.0.1
)を書きました。このスクリプトは、この回答の一番下に投稿します。default route
両方のOが持っているように バッシュ デフォルトでインストールされ、MacとLinuxの両方にbashのヒントがあります。
ロケールの問題は、以下を使用することで防止されますLANG=C
。
myip=
while IFS=$': \t' read -a line ;do
[ -z "${line%inet}" ] && ip=${line[${#line[1]}>4?1:2]} &&
[ "${ip#127.0.0.1}" ] && myip=$ip
done< <(LANG=C /sbin/ifconfig)
echo $myip
最小:
getMyIP() {
local _ip _line
while IFS=$': \t' read -a _line ;do
[ -z "${_line%inet}" ] &&
_ip=${_line[${#_line[1]}>4?1:2]} &&
[ "${_ip#127.0.0.1}" ] && echo $_ip && return 0
done< <(LANG=C /sbin/ifconfig)
}
簡単な使用:
getMyIP
192.168.1.37
getMyIP() {
local _ip _myip _line _nl=$'\n'
while IFS=$': \t' read -a _line ;do
[ -z "${_line%inet}" ] &&
_ip=${_line[${#_line[1]}>4?1:2]} &&
[ "${_ip#127.0.0.1}" ] && _myip=$_ip
done< <(LANG=C /sbin/ifconfig)
printf ${1+-v} $1 "%s${_nl:0:$[${#1}>0?0:1]}" $_myip
}
使用法:
getMyIP
192.168.1.37
または、同じ関数を実行しますが、引数を指定します。
getMyIP varHostIP
echo $varHostIP
192.168.1.37
set | grep ^varHostIP
varHostIP=192.168.1.37
注意:引数なしの場合、この関数はSTDOUT、IP、および改行に出力し、引数を指定しても何も出力されませんが、引数として指定された変数が作成され、改行なしのIPが含まれます。
注2:これは、Debian、LaCieのハッキングされたnasおよびMaxOでテストされました。これがあなたの環境でうまくいかない場合、私はフィードバックに非常に興味があります!
(に基づいてsed
いないため、削除されませんbash
。)
警告:ロケールに関する問題があります!
速くて小さい:
myIP=$(ip a s|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p}')
爆発した(仕事も;)
myIP=$(
ip a s |
sed -ne '
/127.0.0.1/!{
s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p
}
'
)
編集:
どうやって!これはMac OSでは動作しないようです...
[OK]を、この作業は上全く同じように見えるのMac OS私の上などのLinux:
myIP=$(LANG=C /sbin/ifconfig | sed -ne $'/127.0.0.1/ ! { s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p; }')
分割:
myIP=$(
LANG=C /sbin/ifconfig |
sed -ne $'/127.0.0.1/ ! {
s/^[ \t]*inet[ \t]\\{1,99\\}\\(addr:\\)\\{0,1\\}\\([0-9.]*\\)[ \t\/].*$/\\2/p;
}')
このスクリプトは、最初に使用されるデフォルトのルートとインターフェースを見つけ、次にゲートウェイのローカルIPマッチングネットワークを検索して、変数を入力します。最後の2行は次のように表示されます。
Interface : en0
Local Ip : 10.2.5.3
Gateway : 10.2.4.204
Net mask : 255.255.252.0
Run on mac : true
または
Interface : eth2
Local Ip : 192.168.1.31
Gateway : 192.168.1.1
Net mask : 255.255.255.0
Run on mac : false
まあ、それはあります:
#!/bin/bash
runOnMac=false
int2ip() { printf ${2+-v} $2 "%d.%d.%d.%d" \
$(($1>>24)) $(($1>>16&255)) $(($1>>8&255)) $(($1&255)) ;}
ip2int() { local _a=(${1//./ }) ; printf ${2+-v} $2 "%u" $(( _a<<24 |
${_a[1]} << 16 | ${_a[2]} << 8 | ${_a[3]} )) ;}
while IFS=$' :\t\r\n' read a b c d; do
[ "$a" = "usage" ] && [ "$b" = "route" ] && runOnMac=true
if $runOnMac ;then
case $a in
gateway ) gWay=$b ;;
interface ) iFace=$b ;;
esac
else
[ "$a" = "0.0.0.0" ] && [ "$c" = "$a" ] && iFace=${d##* } gWay=$b
fi
done < <(/sbin/route -n 2>&1 || /sbin/route -n get 0.0.0.0/0)
ip2int $gWay gw
while read lhs rhs; do
[ "$lhs" ] && {
[ -z "${lhs#*:}" ] && iface=${lhs%:}
[ "$lhs" = "inet" ] && [ "$iface" = "$iFace" ] && {
mask=${rhs#*netmask }
mask=${mask%% *}
[ "$mask" ] && [ -z "${mask%0x*}" ] &&
printf -v mask %u $mask ||
ip2int $mask mask
ip2int ${rhs%% *} ip
(( ( ip & mask ) == ( gw & mask ) )) &&
int2ip $ip myIp && int2ip $mask netMask
}
}
done < <(/sbin/ifconfig)
printf "%-12s: %s\n" Interface $iFace Local\ Ip $myIp \
Gateway $gWay Net\ mask $netMask Run\ on\ mac $runOnMac
sbin
私の$PATH
フルパスにはないので、指定する必要がありますが、MacOSにも同じパスが存在します。:-)
time
使用して、どれを長く使用するかを選択します...
Ubuntuの特定のビルドのみに固有です。それはあなたに言うかもしれませんが127.0.0.1
:
hostname -i
または
hostname -I
$ hostname --ip-address
127.0.0.1
Arch Linuxについて教えてください
Linuxでこのコマンドを使用して、eth0のIPバージョン4アドレスを取得することもできます。
/sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}'
出力はこのようになります
[root@localhost Sathish]# /sbin/ip -4 -o addr show dev eth0| awk '{split($4,a,"/");print a[1]}'
192.168.1.22
これにより、デフォルトルートに関連付けられたインターフェースが取得されます
NET_IF=`netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}'`
上記で検出されたインターフェースを使用して、IPアドレスを取得します。
NET_IP=`ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'`
uname -a
Darwinラップトップ14.4.0 Darwin Kernelバージョン14.4.0:5月28日木曜日11:35:04 PDT 2015; root:xnu-2782.30.5〜1 / RELEASE_X86_64 x86_64
echo $NET_IF
en5
echo $NET_IP
192.168.0.130
uname -a
Linux dev-cil.medfx.local 2.6.18-164.el5xen 1 SMP Thu Sep 3 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU / Linux
echo $NET_IF
eth0
echo $NET_IP
192.168.46.10
| head -1
デフォルトのインターフェースを取得するには、最初の行の終わりにaが必要なだけで、残りは良好です。
他のいくつかの方法の使用システムで複数のIPアドレスが定義されている場合、競合が発生する可能性があります。この行は常に、デフォルトで使用されるIPアドレスを取得します。
ip route get 8.8.8.8 | head -1 | awk '{print $7}'
ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}'
bash
エイリアスにする場合:alias myip="ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print \$2}'"
Linuxシステムでローカルのipv4-addressを取得する最も簡単な方法:
hostname -I | awk '{print $1}'
デフォルトゲートウェイであるネットワーク内のこのコンピューターのIPアドレスを検索します(たとえば、すべての仮想ネットワーク、Dockerブリッジを除外します)。インターネットゲートウェイ、wifiゲートウェイ、イーサネット
ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
Linuxで動作します。
テスト:
➜ ~ ip route| grep $(ip route |grep default | awk '{ print $5 }') | grep -v "default" | awk '/scope/ { print $9 }'
192.168.0.114
➜ reverse-networking git:(feature/type-local) ✗ ifconfig wlp2s0
wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.114 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::d3b9:8e6e:caee:444 prefixlen 64 scopeid 0x20<link>
ether ac:x:y:z txqueuelen 1000 (Ethernet)
RX packets 25883684 bytes 27620415278 (25.7 GiB)
RX errors 0 dropped 27 overruns 0 frame 0
TX packets 7511319 bytes 1077539831 (1.0 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ifconfig
LinuxとOSXの両方で機能する別のバリエーション:
ifconfig | grep "inet " | cut -f2 -d' '
ifconfig | grep '\<inet\>' | cut -d ' ' -f2 | grep -v '127.0.0.1'
私は多くのリンク(StackExchange、AskUbuntu、StackOverflowなど)をたどって、すべての最適なソリューションを1つのシェルスクリプトに結合することにしました。
私の意見では、これらの2つのQAは最もよく見られます。
シェルスクリプトで外部IPアドレスを取得するにはどうすればよいですか? https://unix.stackexchange.com/q/22615
内部IPアドレスを見つけるにはどうすればよいですか? https://askubuntu.com/a/604691
これは、彼のリポジトリ(https://github.com/rsp/scripts/)で共有されたrspによるいくつかのアイデアに基づく私の解決策です)で。
このスクリプトは非常に単純なタスクでは非常に大きいと言う人もいるかもしれませんが、できるだけ簡単かつ柔軟に使用できるようにしたいと思います。デフォルト値を再定義できる単純な構成ファイルをサポートしています。
Cygwin、MINGW、Linux(Red Hat)でのテストに成功しました。
内部IPアドレスを表示
myip -i
外部IPアドレスを表示
myip -e
ソースコード。リンクからも入手できます:https : //github.com/ildar-shaimordanov/tea-set/blob/master/home/bin/myip。設定ファイルの例は、メインスクリプトの隣にあります。
#!/bin/bash
# =========================================================================
#
# Getting both internal and external IP addresses used for outgoing
# Internet connections.
#
# Internal IP address is the IP address of your computer network interface
# that would be used to connect to Internet.
#
# External IP address is the IP address that is visible by external
# servers that you connect to over Internet.
#
# Copyright (C) 2016 Ildar Shaimordanov
#
# =========================================================================
# Details of the actual implementation are based on the following QA:
#
# How can I get my external IP address in a shell script?
# https://unix.stackexchange.com/q/22615
#
# How do I find my internal ip address?
# https://askubuntu.com/a/604691
# =========================================================================
for f in \
"$( dirname "$0" )/myip.conf" \
~/.myip.conf \
/etc/myip.conf
do
[ -f "$f" ] && {
. "$f"
break
}
done
# =========================================================================
show_usage() {
cat - <<HELP
USAGE
$( basename "$0" ) [OPTIONS]
DESCRIPTION
Display the internal and external IP addresses
OPTIONS
-i Display the internal IP address
-e Display the external IP address
-v Turn on verbosity
-h Print this help and exit
HELP
exit
}
die() {
echo "$( basename "$0" ): $@" >&2
exit 2
}
# =========================================================================
show_internal=""
show_external=""
show_verbose=""
while getopts ":ievh" opt
do
case "$opt" in
i )
show_internal=1
;;
e )
show_external=1
;;
v )
show_verbose=1
;;
h )
show_usage
;;
\? )
die "Illegal option: $OPTARG"
;;
esac
done
if [ -z "$show_internal" -a -z "$show_external" ]
then
show_internal=1
show_external=1
fi
# =========================================================================
# Use Google's public DNS to resolve the internal IP address
[ -n "$TARGETADDR" ] || TARGETADDR="8.8.8.8"
# Query the specific URL to resolve the external IP address
[ -n "$IPURL" ] || IPURL="ipecho.net/plain"
# Define explicitly $IPCMD to gather $IPURL using another tool
[ -n "$IPCMD" ] || {
if which curl >/dev/null 2>&1
then
IPCMD="curl -s"
elif which wget >/dev/null 2>&1
then
IPCMD="wget -qO -"
else
die "Neither curl nor wget installed"
fi
}
# =========================================================================
resolveip() {
{
gethostip -d "$1" && return
getent ahostsv4 "$1" \
| grep RAW \
| awk '{ print $1; exit }'
} 2>/dev/null
}
internalip() {
[ -n "$show_verbose" ] && printf "Internal: "
case "$( uname | tr '[:upper:]' '[:lower:]' )" in
cygwin* | mingw* | msys* )
netstat -rn \
| grep -w '0.0.0.0' \
| awk '{ print $4 }'
return
;;
esac
local t="$( resolveip "$TARGETADDR" )"
[ -n "$t" ] || die "Cannot resolve $TARGETADDR"
ip route get "$t" \
| awk '{ print $NF; exit }'
}
externalip() {
[ -n "$show_verbose" ] && printf "External: "
eval $IPCMD "$IPURL" $IPOPEN
}
# =========================================================================
[ -n "$show_internal" ] && internalip
[ -n "$show_external" ] && externalip
# =========================================================================
# EOF
私はネットワークインターフェイス名を利用しているだけで、カスタムコマンドは
[[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
私自身のノート
[flying@lempstacker ~]$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[flying@lempstacker ~]$ [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
192.168.2.221
[flying@lempstacker ~]$
しかし、ネットワークインターフェースが少なくとも1つのIPを所有している場合、すべてのIPがそれに属していることが表示されます。
例えば
Ubuntu 16.10
root@yakkety:~# sed -r -n 's@"@@g;s@^VERSION=(.*)@\1@p' /etc/os-release
16.04.1 LTS (Xenial Xerus)
root@yakkety:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
178.62.236.250
root@yakkety:~#
Debianジェシー
root@jessie:~# sed -r -n 's@"@@g;s@^PRETTY_NAME=(.*)@\1@p' /etc/os-release
Debian GNU/Linux 8 (jessie)
root@jessie:~# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
192.81.222.54
root@jessie:~#
CentOS 6.8
[root@centos68 ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@centos68 ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
162.243.17.224
10.13.0.5
[root@centos68 ~]# ip route get 1 | awk '{print $NF;exit}'
162.243.17.224
[root@centos68 ~]#
Fedora 24
[root@fedora24 ~]# cat /etc/redhat-release
Fedora release 24 (Twenty Four)
[root@fedora24 ~]# [[ $(ip addr | grep enp0s25) != '' ]] && ip addr show dev enp0s25 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p' || ip addr show dev eth0 | sed -n -r 's@.*inet (.*)/.*brd.*@\1@p'
104.131.54.185
10.17.0.5
[root@fedora24 ~]# ip route get 1 | awk '{print $NF;exit}'
104.131.54.185
[root@fedora24 ~]#
リンクip route get 1 | awk '{print $NF;exit}'
によって提供されるそのコマンドはより正確であるように見えます。
これがすべてのOSで機能するかどうかわからない場合は、試してください。
ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}'
ip route get 1 | awk '{print $NF;exit}'
ます。ほとんどのシステムで動作するはずです。
ip route get 1 | awk '{print $NF;exit}'
機能します
ifconfig | grep "inet addr:" | grep -v "127.0.0.1" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1
Mac、Linux、およびDockerコンテナー内で動作します。
$ hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print
$ 1; 出口}')
次のようにも機能しMakefile
ます:
LOCAL_HOST := ${shell hostname --ip-address 2> /dev/null || (ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | awk '{print $1; exit}')}
hostname --ip-address
=> hostname: illegal option -- -
macOS Sierraで
Linuxの場合、次のコマンドが必要です。
ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }'
これをシェルに入力すると、IPがわかります。
これは読みやすいです:
ifconfig | grep 'inet addr:' |/usr/bin/awk '{print $2}' | tr -d addr: