127.0.0.1 以外の、localhost のプライマリ (最初の) IP アドレスを返すコマンド ライン ソリューションを探しています。
このソリューションは、少なくとも Linux (Debian および RedHat) および OS X 10.7 以降では機能するはずです。
両方で利用できることは承知してifconfig
いますが、その出力はこれらのプラットフォーム間であまり一貫していません。
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 のみです。
以下は Linux では機能しますが、OSX では機能しません。
これは DNS にまったく依存せず、/etc/hosts
が正しく設定されていなくても機能します (1
は の省略形です1.0.0.0
)。
ip route get 1 | awk '{print $NF;exit}'
awk
または、明白にするために、Google のパブリック DNS を避けて使用します8.8.8.8
。
ip route get 8.8.8.8 | head -1 | cut -d' ' -f8
信頼性の低い方法: (以下のコメントを参照)
hostname -I | cut -d' ' -f1
Linux マシン (OS X 以外) の場合:
hostname --ip-address
少し前から、今は新しい ip
ツールを使用しています。しかし、bashの下では、単純に次のようにします。
read -r _{,} gateway _ iface _ ip _ < <(ip r g 1.0.0.0)
それで
printf '%-12s %s\n' gateway $gateway iface $iface ip $ip
gateway 192.168.1.1
iface eth0
ip 192.168.1.37
そこから、マスクは次のとおりです。
while IFS=$' /\t\r\n' read lne lip lmask _;do
[ "$lne" = "inet" ] && [ "$lip" = "$ip" ] && mask=$lmask
done < <(ip a s dev $iface)
echo Mask is $mask bits.
Mask is 24 bits.
次に、マスクを IP として表示する場合:
printf -v msk '%*s' $mask ''
printf -v msk %-32s ${msk// /1}
echo $((msk=2#${msk// /0},msk>>24)).$((msk>>16&255)).$((msk>>8&255)).$((msk&255))
255.255.255.0
多くのインターフェイスと各インターフェイスに多くの IP が構成されたより強力な構成のために、に基づいて正しいインターフェイスとIPを見つけるための純粋な bashスクリプト (に基づいていない) を作成しました。このスクリプトは、この回答の一番下に投稿します。127.0.0.1
default route
どちらの Os にもデフォルトでbashがインストールされているため、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 および newline に出力します。引数がある場合、何も出力されませんが、引数として名前が付けられた変数が作成され、newlineのない IP が含まれます。
注 2:これは、Debian、LaCie ハッキングされた NAS および MaxOs でテストされました。これがあなたの環境でうまくいかない場合は、フィードバックに非常に興味があります!
( に 基づい て いる ため 削除 し て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では動作しないようです...
わかりました、これは私のLinuxと同じようにMac OSで動作するようです:
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
Ubuntu の特定のビルドのみに固有です。それはあなたに言うだけかもしれませんが127.0.0.1
:
hostname -i
また
hostname -I
Primary network interface IP
ifconfig `ip route | grep default | head -1 | sed 's/\(.*dev \)\([a-z0-9]*\)\(.*\)/\2/g'` | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | head -1
ifconfig
Linux と OSX の両方で動作する別のバリエーション:
ifconfig | grep "inet " | cut -f2 -d' '
ip addr show | grep -E '^\s*inet' | grep -m1 global | awk '{ print $2 }' | sed 's|/.*||'
多くのリンク (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
これがすべての OS で機能するかどうかはわかりませんが、試してみてください。
ifconfig | awk -F"[ :]+" '/inet addr/ && !/127.0/ {print $4}'
すべてのノード パッケージがあります。クロスプラットフォームで使いやすいです。
$ npm install --global internal-ip-cli
$ internal-ip
fe80::1
$ internal-ip --ipv4
192.168.0.3
これは物議を醸すアプローチですが、好むと好まざるとにかかわらず、ツールに npm を使用することがより一般的になりつつあります。
ifconfig $(netstat -rn | grep -E "^default|^0.0.0.0" | head -1 | awk '{print $NF}') | grep 'inet ' | awk '{print $2}' | grep -Eo '([0-9]*\.){3}[0-9]*'
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 では、次の点を考慮してください。
scutil --nwi | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'