Thay đổi nội dung ( 2014/06/01 2018/01/09)
Để cấu hình mạnh hơn, với nhiều giao diện và nhiều IP được cấu hình trên mỗi giao diện, tôi đã viết một tập lệnh bash thuần túy (không dựa trên 127.0.0.1
) để tìm giao diện và ip chính xác , dựa trên default route
. Tôi đăng kịch bản này ở dưới cùng của câu trả lời này.
Giới thiệu
Như cả Os đều có bash được cài đặt theo mặc định, có một mẹo bash cho cả Mac và Linux:
Vấn đề bản địa được ngăn chặn bằng cách sử dụng 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
Đưa chức năng này vào một chức năng:
Tối thiểu:
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)
}
Sử dụng đơn giản:
getMyIP
192.168.1.37
Fancy gọn gàng:
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
}
Sử dụng:
getMyIP
192.168.1.37
hoặc, chạy cùng chức năng, nhưng với một đối số:
getMyIP varHostIP
echo $varHostIP
192.168.1.37
set | grep ^varHostIP
varHostIP=192.168.1.37
Ghi chú: Không có đối số, hàm này xuất ra trên STDOUT, IP và một dòng mới , với một đối số, không có gì được in, nhưng một biến có tên là đối số được tạo và chứa IP không có dòng mới .
Nota2: Điều này đã được thử nghiệm trên Debian, LaCie đã hack Nas và MaxOs. Nếu điều này không hoạt động trong môi trường của bạn, tôi sẽ rất quan tâm bởi các phản hồi!
Phiên bản cũ hơn của câu trả lời này
(Không bị xóa vì dựa trên sed
, không bash
.)
Cảnh báo: Có một vấn đề về địa phương!
Nhanh và nhỏ:
myIP=$(ip a s|sed -ne '/127.0.0.1/!{s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p}')
Phát nổ (làm việc quá;)
myIP=$(
ip a s |
sed -ne '
/127.0.0.1/!{
s/^[ \t]*inet[ \t]*\([0-9.]\+\)\/.*$/\1/p
}
'
)
Biên tập:
Làm sao! Điều này dường như không hoạt động trên Mac OS ...
Ok, điều này có vẻ hoạt động khá giống nhau trên Mac OS như trên Linux của tôi :
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; }')
tách ra:
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;
}')
Kịch bản của tôi (tháng 1 năm 2018):
Tập lệnh này trước tiên sẽ tìm thấy tuyến đường và giao diện mặc định của bạn được sử dụng, sau đó tìm kiếm mạng kết hợp ip cục bộ của các cổng và biến dân số. Hai dòng cuối cùng chỉ in, đại loại như:
Interface : en0
Local Ip : 10.2.5.3
Gateway : 10.2.4.204
Net mask : 255.255.252.0
Run on mac : true
hoặc là
Interface : eth2
Local Ip : 192.168.1.31
Gateway : 192.168.1.1
Net mask : 255.255.255.0
Run on mac : false
Vâng, đó là:
#!/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