내 자신의 IP 주소를 가져 와서 셸 스크립트의 변수에 어떻게 저장할 수 있습니까?
내 자신의 IP 주소를 가져 와서 셸 스크립트의 변수에 어떻게 저장할 수 있습니까?
답변:
무선 랜 및 기타 대체 인터페이스를 고려하고 싶을 때는 쉽지 않습니다. 주소를 원하는 인터페이스를 알고있는 경우 (예 : 첫 번째 이더넷 카드 인 eth0) 다음을 사용할 수 있습니다.
ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
즉, 찾아 내게 네트워크 구성 정보를 얻을 eth0
, 그 선하고 다음을 (수 -A 1
), 얻을 단지 로 분할 할 때 마지막 줄을, 그 라인의 두 번째 부분을 얻을 :
분할 할 때, 그의 첫 번째 부분을 얻을 공간이 있습니다.
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
내 opionion에서 훨씬 더 구문 분석 가능합니다.
ip
내가 본 모든 데비안 및 데비안 기반 배포판에서도 사용할 수 있습니다. 중요한 것으로 표시되는 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-ADRESS ... 제공
-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
출력 을 구문 분석하려는 유혹을받는 모든 질문에 거의 응답 합니다.
외부에서 보는 것처럼 (NAT 등을 제외하고) IP 주소를 찾으려면 수행 할 서비스가 많이 있습니다. 하나는 매우 쉽습니다.
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)
-o
용이 한 라인 출력 형식으로 처리하는 데 사용 read
, grep
등up
활성화되지 않은 장치는 제외scope global
제외 / 개인 등의 로컬 주소 127.0.0.1
및fe80::/64
primary
임시 주소 제외 (변경되지 않는 주소를 원한다고 가정)-4
/ -6
를 전달 하여 주소 유형을 필터링 할 수 있습니다 . 다른 인터페이스 매개 변수를 쉽게 얻을 수도 있습니다. 개인적으로, 나는 while 루프를 싫어하고 선호합니다grep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
자신의 IP 주소가 의미하는 바에 따라 다릅니다. 시스템에는 여러 서브넷 (때로는 서브넷 당 여러 개)에 IP 주소가 있으며, 일부는 IPv4, 일부는 이더넷 어댑터, 루프백 인터페이스, VPN 터널, 브리지, 가상 인터페이스와 같은 장치를 사용하는 IPv6을 사용합니다.
다른 장치가 컴퓨터에 도달 할 수있는 IP 주소를 의미합니다. 어떤 서브넷인지, 어떤 IP 버전을 말하는지 알아야합니다. 또한 방화벽 / 라우터에 의해 수행 된 NAT 때문에 원격 호스트가 컴퓨터에서 들어오는 연결을 보는 것과 인터페이스의 IP 주소가 동일하지 않을 수 있습니다.
멋진 소스 라우팅 또는 프로토콜 / 포트 라우팅이있을 때 주어진 프로토콜을 통해 하나의 원격 컴퓨터와 통신하는 데 어떤 인터페이스가 사용되는지 알아 내기 어려울 수 있으며, 그 경우에도 해당 인터페이스의 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은 내 컴퓨터의 DNS 요청이 개인 IP 주소에서 오는 것으로 보지 않습니다.
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
당신이 루프백 adresses를 무시하려는 것처럼 더 나은, 그래서 최종 명령이 될 것이다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
명령 에 대한 추가 정보먼저 유닉스 도구를 선택할 때 가장 적은 파이프가 필요한 도구를 선택하려고합니다. 그래서, 반면 어떤 답변 파이프 의지 ifconfig
에 grep
에가 sed
로 head
, 즉 거의 이제까지 필요하지 않습니다. 당신이 그것을 볼 때, 그것은 당신이 거의 경험이없는 사람으로부터 조언을하고 붉은 깃발을 제기해야합니다. "솔루션"을 잘못 만들지는 않습니다. 그러나 아마도 약간의 간소화를 사용할 수 있습니다.
sed
의 동일한 워크 플로보다 더 간결하기 때문에 선택 했습니다 awk
. (아래에 awk 예제가 있습니다.) 다른 도구는 없지만 그 두 가지가 적절하다고 생각합니다.
무엇을하는지 살펴 보자 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}}}'
내 VPN 및 LAN에 대한 ifconfig
쇼가 있습니다 .tun0
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)
ip route get 8.8.8.8 | sed -n '/src/{s/.*src *//p;q}'
나에게 주었다 10.1.2.3 uid 1002
. 따라서 | awk '{print $1}'
IP 주소 만 유지하기 위해 추가 합니다.
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 \"
IPv4 또는 IPv6 주소 dig(1)
와 같은 -4
또는 -6
구체적으로 옵션을 사용할 수 있습니다 . Google은 TXT
형식 레코드로 답변을 제공합니다 dig
. 이후에 유틸리티와 함께 변수를 사용하려면 tr (1)traceroute
과 같은 것을 사용 하여 따옴표를 제거해야합니다.
다른 옵션으로는 whoami.akamai.net
and가 있으며 myip.opendns.com
, 위의 예에서와 같이 대답 A
하고 AAAA
기록 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 / 리눅스) ip addr
(GNU / 리눅스), hostname
(옵션 -i
및 -I
에 GNU / Linux) 및 netstat
진행 상황을 확인하십시오.
hostname -I >> file_name
이것은 당신이 원하는 모든 것을 할 것입니다
hostname: invalid option -- 'l'
...