Kendi IP adresimi nasıl alabilirim ve bir kabuk betiğindeki bir değişkene nasıl kaydedebilirim?
Kendi IP adresimi nasıl alabilirim ve bir kabuk betiğindeki bir değişkene nasıl kaydedebilirim?
Yanıtlar:
WLAN ve diğer alternatif arayüzleri dikkate almak istiyorsanız o kadar kolay değil. Hangi arabirim için adres istediğinizi biliyorsanız (örneğin, eth0, ilk Ethernet kartı), bunu kullanabilirsiniz:
ip="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
Başka bir deyişle, bana ağ yapılandırma bilgilerini verin, arayın eth0
, bu satırı ve sonuncusunu ( -A 1
) alın, yalnızca son satırı alın, bölme sırasında bu satırın ikinci kısmını :
alın, sonra bölmenin olduğu zaman ilk kısmını alın boşluk ile.
grep
İçinde "eth0:" olan herhangi bir arayüzü görmezden gelmek için kodunuza bir ek ekledim ; bu şimdi beklediğim gibi çalışıyor (sadece "eth0" IP adresi veriyor ve herhangi bir alt arayüz değil (eth0: 0, eth0: 1, vs.):ip="$(ifconfig | grep -v 'eth0:' | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
ifconfig eth0
ip address
bunun yerine kullanmalısınız
IPv4 adresinizi almanın "modern araçlar" yolunun 'ifconfig' yerine 'ip' i ayrıştırmak olduğuna inanıyorum, bu yüzden şöyle bir şey olurdu:
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)
ya da böyle bir şey.
ip
Kullandığım tüm Red Hat ve Fedora dağıtımlarında kullanılabilir. ip
iproute2 paketinin bir parçasıdır ( linuxfoundation.org/collaborate/workgroups/networking/iproute2 ). ifconfig
ve route
çoğu kişi tarafından, özellikle senaryolarda kullanılmaya devam etmelerine rağmen, sözde itiraz edilmektedir. ip
benim görüşüme göre, çok daha ayrıştırılabilir.
ip
Ayrıca gördüğüm tüm Debian ve Debian dağıtımlarına da açık. Önemli olarak işaretlenen iproute paketinin bir parçası.
ip
iproute2 paketinin bir parçası olan, varsayılan olarak bir dağıtımdır. En iyi repolarda var. en.wikipedia.org/wiki/Iproute2
/sbin/ip
yerine ip
?
awk
ve cut
bana biraz eğlendirici geliyor, işte aslında daha iyi olmayabilir muhtemel bir alternatif:ip -o -4 addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }'
Neden sadece yapmıyorsun IP=$(hostname -I)
?
hostname -i
Sadece bana verir 127.0.0.1
, hostname -I
bana doğru IP-Adres ... verir
-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 adresiyle birlikte bu adrese eklemektir
-I
FreeBSD'de hayır , ama kullanabilirsinizdig +short `hostname -f`
Bir arabirimin adresini istiyorsanız, en kolay yol daha sonra başka şeyler yüklemektir:
anthony@Zia:~$ ifdata -pa br0
172.16.1.244
ifdata
ifconfig
çıktılarını ayrıştırmak isteyeceğiniz her soruyu hemen hemen yanıtlar .
IP adresinizi dışarıdakilerin gördüğü gibi (NAT hariç, vb.) Öğrenmek istiyorsanız, yapacak birçok hizmet vardır. Biri oldukça kolaydır:
anthony@Zia:~$ curl ifconfig.me
173.167.51.137
ifdata
eklenir iproute2
. Belki de denilen yeni bir ikiliipdata
IPv4 ve IPv6 adreslerini almak ve ana arabirimin eth0
(bu günler em1
daha yaygın ) olduğunu varsaymamak için , şunu deneyin:
ips=$(ip -o addr show up primary scope global |
while read -r num dev fam addr rest; do echo ${addr%/*}; done)
-o
kolay olan bir hat çıkış biçimi ile işlemek için kullanır read
, grep
vbup
aktif olmayan cihazları hariç tutarscope global
dışlayan özel / gibi yerel adresleri 127.0.0.1
vefe80::/64
primary
geçici adresleri hariç tutar (değişmeyen bir adres istediğinizi varsayarsak)-4
/ geçirmek -6
için kullanabilirsiniz. Diğer arayüz parametrelerini de kolayca alabilirsiniz. Şahsen ben döngü iken sevmiyorum ve tercih ederimgrep -o 'inet6\? [0-9a-f\.:]*' | cut -f 2 -d ' '
Ne demek istediğinizi kendi IP adresinize göre değişir. Sistemler, IPv4'ü, bazıları IPv6'ı ethernet adaptörleri, loopback arayüzleri, VPN tünelleri, köprüler, sanal arayüzler ...
Başka bir cihazın bilgisayarınıza erişebileceği IP adresini, yani hangi alt ağı ve hangi IP sürümünden bahsettiğimizi öğrenmeniz gerekir. Ayrıca, güvenlik duvarı / yönlendiriciler tarafından gerçekleştirilen NAT nedeniyle, bir arabirimin IP adresinin uzaktaki bir ana bilgisayarla aynı olmayabileceğini, bilgisayarınızdan gelen bir bağlantıyı gördüğünü unutmayın.
Fantezi kaynak yönlendirmesi veya protokol / port yönlendirmesi olduğunda, belirli bir protokol üzerinden bir uzak bilgisayarla hangi arabirimin konuşacağını bulmak zor olabilir ve o zaman bile bu arabirimin IP adresinin olabileceğinin garantisi yoktur. Bilgisayarınızla yeni bir bağlantı kurmak isteyen uzak bilgisayar tarafından doğrudan adreslenebilir.
IPv4 için (muhtemelen IPv6 için de çalışır), belirli bir ana bilgisayara ulaşmak için kullanılan arabirimin IP adresini bulmak için Linux dahil birçok birimde çalışan bir püf noktası, bir UDP soketinde bir connect (2) kullanmak ve getsockname kullanmaktır. ():
Örneğin, ev bilgisayarımda:
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'e (google'ın DNS sunucusu) ulaşacağım arayüzün IP adresini bulmak için kullanılır. İnternete varsayılan yol için arabirimin adresi olan "192.168.1.123" gibi bir şey döndürecekti. Ancak, google ev genişbant yönlendiricim tarafından gerçekleştirilen NAT olduğu için, özel bir IP adresinden gelen, makinemden gelen bir DNS isteğini görmedi.
UDP soketindeki connect () herhangi bir paket göndermez (UDP bağlantısız), ancak yönlendirme tablosunu sorgulayarak soketi hazırlar.
ipa=$(ip route get 8.8.8.8| grep src| sed 's/.*src \(.*\)$/\1/g')
ipa=$(hostname -i|cut -f2 -d ' ')
-I
Bunun yerine kullanmak -i
, geri döngü adreslerini yoksaymak isteyeceğinizden daha iyidir, bu yüzden son komut şu şekilde olacaktıripa=$(hostname -I|cut -f1 -d ' ')
grep
yeterli değil, başka bir şey boru yok. Sadece başka bir şey (kullanmak sed
, awk
vb.)
Pislik olmak istemem, ama gerçekten doğru bir yol var ve hepsi bu. ip route
Yalnızca kaynak IP'yi elde etmek için çıktısını kesersiniz. Hangi IP'ye erişmeye çalıştığınıza bağlı olarak, "kendi ip adresim" (OP'nin kelimeleri) farklı olacaktır. Halka açık internete ulaşmak istiyorsanız Google’ın 8.8.8.8 DNS sunucusunu kullanmak oldukça standart. Yani...
ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
İnternete ulaşmak için kullandığım ipi istersem şunu kullanırım :
pi@et3:~ $ ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
10.55.0.200
Benim bir şey erişmek için kullandığı ip istiyorsanız VPN , bunu kullanmaktan:
pi@et3:~ $ ip route get 172.31.0.100 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'
172.29.0.9
Bu bir sonraki gerçekten sadece örnek amaçlıdır. Ancak, herhangi bir Linux sisteminde çalışmalıdır. Böylece, bunu, tüm makinelerin her zaman birden fazla IP adresine sahip olduğunu göstermek için kullanabilirsiniz.
Eğer kendime ulaşmak için kullandığım ipi isteseydim bunu kullanırdım:
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
komut hakkında daha fazlasıÖncelikle, unix aletlerini seçerken, en az boru gerektiren aletleri seçmeye çalıştığınızı söylememe izin verin. Yani, sırasında bazı cevaplar boru olacak ifconfig
etmek grep
için sed
için head
, o çok nadir gereklidir. Gördüğünüz zaman, çok az deneyime sahip birinden tavsiye aldığınız bir kırmızı bayrağı kaldırmanız gerekir. Bu "çözümü" yanlış yapmaz. Ancak, muhtemelen bazı düzene kullanabilirsiniz.
Ben seçtim sed
çünkü aynı iş akışından daha özlü awk
. (Aşağıda bir awk örneğinden beri var.) Başka bir araç düşünmüyorum ama bu 2 uygun olacaktır.
Ne yaptığını inceleyelim 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
Not:
Eskiden kullanırdım sed -n '/src/{s/.*src *//p;q}'
ama bir yorumcu bazı sistemlerin src
sahadan sonra takip eden verileri olduğunu belirtti .
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}}}'
Benim ifconfig
Ben gösterir tun0
benim VPN için ve eth0
benim lan için.
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}'
bana verdi 10.1.2.3 uid 1002
. Bu yüzden | awk '{print $1}'
sadece IP adresini tutmak için eklemek için eklerim .
FreeBSD'de kullanabilirsiniz
dig +short `hostname -f`
Bu, diğer ortamlar için işe yarayabilir, kurulumunuza bağlıdır.
/etc/resolv.conf
ağ yönlendiricisinin yapılandırmasına ve yerel ana bilgisayar adlarını nasıl kullandığına bağlı olduğunu düşünüyorum . Test edip işe yarıyorsa, bunu ortamınızda kullanmanız iyidir . Ancak, bunu yaparsanız, paylaşırsanız başkalarına sorun çıkaran bir "kırılgan" sistem kuruyorsunuz. Dikkatle kullanın.
Çeşitli adda çeşitli arayüzlere sahip olabileceğinizi, ancak ilk localhost olmayan ve ipv6 olmayanları istediğinizi varsayalım:
ip=`ip addr show |grep "inet " |grep -v 127.0.0. |head -1|cut -d" " -f6|cut -d/ -f1`
Bu tek astarı kullanıyorum:
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-)
Kullanımlar ifconfig
(yaygın olarak bulunur), localhost
adres almaz, sizi belirli bir arayüz adına bağlamaz, IPv6'yı dikkate almaz ve mevcut ilk ağ arayüzünün IP'sini almaya çalışır.
Sen kullanmalıdır ip
(yerine ifconfig
bir tutarlı ve ayrıştırılamaz çıktı üretir, komut dosyası amaçlı en önemlisi belki de muhafaza akım var gibi) ve. Aşağıdaki birkaç benzer yaklaşım vardır:
Ethernet arayüzünüz için IPv4 adresini istiyorsanız eth0
:
$ ip -4 -o addr show eth0 | awk '{print $4}'
192.168.1.166/24
Bir komut dosyası olarak:
$ INTFC=eth0
$ MYIPV4=$(ip -4 -o addr show $INTFC | awk '{print $4}')
$ echo $MYIPV4
192.168.1.166/24
Yukarıda üretilen çıktı CIDR notasyonundadır. CIDR notasyonu istenmiyorsa, sıyrılabilir:
$ ip -4 -o addr show eth0 | awk '{print $4}' | cut -d "/" -f 1
192.168.1.166
IMHO'nun "en şık" olduğu bir diğer seçenek, belirtilen uzak ana bilgisayara bağlanmak için hangi arabirim için kullanılıyorsa IPv4 adresini alır (bu durumda 8.8.8.8). Bu cevapta @ gatoatigrado izniyle :
$ ip route get 8.8.8.8 | awk '{ print $NF; exit }'
192.168.1.166
Bir komut dosyası olarak:
$ RHOST=8.8.8.8
$ MYIP=$(ip route get $RHOST | awk '{ print $NF; exit }')
$ echo $MYIP
192.168.1.166
Bu, tek bir arayüze sahip bir ana bilgisayarda mükemmel şekilde çalışır, ancak daha avantajlı bir şekilde birden fazla arayüze ve / veya rota özelliklerine sahip ana bilgisayarlar üzerinde de çalışır.
ip
benim tercih ettiğim yaklaşım olurdu, ama kesinlikle bu kedinin derisinin tek yolu bu değil. İşte hostname
daha kolay / daha özlü bir şey tercih ederseniz kullanan başka bir yaklaşım :
$ hostname --all-ip-addresses | awk '{print $1}'
Veya IPv6 adresini istiyorsanız:
$ hostname --all-ip-addresses | awk '{print $2}'
Bunu, kablolu NIC'imde bir radyo sunucusunu başlatmak için bir takma ad içinde yapmam gerekiyordu. kullandım
ip addr | egrep -i "inet.+eth1" | awk -F[\ /] '{print $6}' | tr -d [:space:]
egrep
amortismana tabi tutulmuştur. Yerine grep -E
kullanın.
Bazı komutlar 6 veya 7 numaralı centos üzerinde çalışıyor, aşağıdaki komut her ikisinde de çalışıyor
#!/bin/sh
serverip=`/sbin/ifconfig eth0 | grep "inet" | awk '{print $2}' | awk 'NR==1' | cut -d':' -f2`
echo $serverip
grep | awk | awk
. çizgi kısaltılabilir/sbin/ifconfig eth0 | awk '$1 == "inet" { print substr($2,6); next ; } '
Bu parçacık ( 'eth0' gibi) cihazın adını sabit kodlama ve kullanacaktır önler ip
yerine ifconfig
:
/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'
Çıktısında listelenen ilk etkin cihazın IP'sini döndürür ip addr
. Makinenize bağlı olarak, bu bir ipv4 veya ipv6 adresi olabilir.
Bir değişkende saklamak için şunu kullanın:
ip=$(/sbin/ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
awk / sed / grep komutunu kullanan tüm çözümler durumum için aşırı karmaşık ve çirkin görünüyor ... bu yüzden bu gerçekten basit bir çözüm buldum, ancak bazı varsayımlar yapan cus'a dikkat edin, yani LAST arayüzünün kendinizin olduğu varsayımı. Ilgilenen. Eğer onunla iyiysen, o zaman bu oldukça temiz:
ifconfig | awk '/net / { x = $2 } END { print x }'
Aksi halde if
, belirli bir önek veya sahip olabileceğiniz ölçütleri test etmek için bazı aptalca ifadeler yapabilirsiniz .
Kutunun ortak bir IP adresini arıyorsanız , aşağıdakileri kullanabilirsiniz:
dig @ns1.google.com -t txt o-o.myaddr.l.google.com +short | tr -d \"
Bir IPv4 veya IPv6 adresi dig(1)
gibi -4
veya -6
özellikle aramak için seçenekleri kullanabilirsiniz ; Google, TXT
türüne göre teklif edildiğinde etrafından alıntılar yapacak bir tür kayıtta bir cevap verecektir dig
; Daha sonra değişkeni bu gibi yardımcı programlarla traceroute
kullanmak istiyorsanız, bahsedilen alıntıları kaldırmak için tr (1) gibi bir şey kullanmanız gerekir .
Diğer seçenekler arasında whoami.akamai.net
ve myip.opendns.com
hangi cevapları A
ve AAAA
kayıtları ( TXT
Google'dan yukarıdaki örnekte olduğu gibi) içerir; bu nedenle, alıntıların kaldırılmasını gerektirmezler:
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
Değişkenleri ayarlamak için yukarıdaki tüm seçenekleri kullanan örnek bir komut dosyası:
#!/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}"
Eğer özel bir IP adresi arıyorsanız, veya kutuya atanan tüm IP adreslerinin kümesi için, size bazı kombinasyonu kullanabilirsiniz ifconfig
, (BSD ve GNU / Linux üzerinde) ip addr
(GNU / Linux üzerinde), hostname
(seçenekleri -i
ve -I
üzerinde GNU / Linux) ve netstat
neler olup bittiğini görmek için.
hostname -I >> file_name
bu istediğin her şeyi yapacak
hostname: invalid option -- 'l'
...