Lệnh đầu cuối nào để chỉ lấy địa chỉ IP và không có gì khác?


118

Tôi đang cố gắng chỉ sử dụng địa chỉ IP (inet) làm tham số trong tập lệnh mà tôi đã viết.

Có cách nào dễ dàng trong một thiết bị đầu cuối unix để chỉ lấy địa chỉ IP, thay vì xem qua ifconfigkhông?


Vâng, hoặc bất kỳ số nhận dạng duy nhất nào khác về máy mà tôi cho là.
Mason

1
bạn nhận được một tùy chọn không hợp lệ trên tên máy chủ -i?
Ken

4
hostname là không đáng tin cậy như ifconfig
joel

2
joel là đúng, đặc biệt bạn nơi nói về hệ điều hành MAC và sau đó Ubuntu
zackaryka

2
Khi duyệt qua các câu trả lời bên dưới, hãy nhớ rằng đầu ra của ip -o addressdễ làm việc hơn nhiều so với đầu ra của ip address.
jlh

Câu trả lời:


177

Bạn có thể viết một tập lệnh chỉ trả về IP như:

/sbin/ifconfig eth0 | grep 'inet addr' | cut -d: -f2 | awk '{print $1}'

Đối với MAC:

ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d\  -f2

Hoặc cho hệ thống linux

hostname -i | awk '{print $3}' # Ubuntu 

hostname -i # Debian

4
hostname -icủa tôi, nó trở lại:::1 127.0.1.1 192.168.1.100
Book Of Zeus

1
Trên Debian, tôi chỉ có một ip. Vì vậy, sử dụng hostnamekhông phải là di động.
Timofey Stolbov

1
Nó nói rằng -i và -Tôi là cả hai lựa chọn bất hợp pháp
Mason

3
Tóm lại: phương pháp đầu tiên phụ thuộc vào bộ điều hợp, không phải lúc nào cũng giống nhau. Địa chỉ thứ hai, đối với tôi, hiển thị hai địa chỉ IP và hai địa chỉ cuối cùng không hoạt động trên Mac.
Matt,

4
ifconfig không được chấp nhận và không đáng tin cậy ở đây, ví dụ: grep không thành công trên debian 9 (căng) vì nó không xuất ra "inet addr: 172.17.0.4" nữa, nó chỉ xuất ra "inet 172.17.0.4". Sử dụng "ip" thay thế như được mô tả trong stackoverflow.com/a/26694162/72717 .
jamhid

61

Điều này sẽ cung cấp cho bạn tất cả các giao diện IPv4, bao gồm cả loopback 127.0.0.1:

ip -4 addr | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

Điều này sẽ chỉ hiển thị eth0:

ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

Và bằng cách này, bạn có thể nhận được địa chỉ IPv6:

ip -6 addr | grep -oP '(?<=inet6\s)[\da-f:]+'

Chỉ eth0IPv6:

ip -6 addr show eth0 | grep -oP '(?<=inet6\s)[\da-f:]+'

Các grep -oPthất bại trên busybox v1.24.1: không hợp lệ tùy chọn - P
Pro Sao lưu

1
grep không được cài đặt trên hầu hết các conatiner docker cho sản phẩm. Vì vậy, mặc dù đây là tất cả các lệnh tốt, chúng sẽ không hữu ích trên các vùng chứa :-(
AndyGee 27/02/19

1
Câu trả lời tốt nhất cho trường hợp cụ thể của tôi. Bạn cần -Pchuyển đổi cho biểu thức chính quy Perl hoặc nếu không, chúng tôi không thể sử dụng (?<=inet\s)mã thông báo lookbehind . Bạn có thể nhận được kết quả tương tự bằng cách chạy grep -oe 'inet [0-9\.]\+'hoặc grep -oe 'inet6 [0-9a-f:]\+'nhưng bằng cách này, tôi không thể loại bỏ từ đầu tiên. Trong man grepbáo cáo SuSE rằng -Pcờ là thử nghiệm.
Jorge Bellon

Đây là câu trả lời tốt nhất. ifconfig đã không còn được chấp nhận vài năm nay trên hầu hết các hệ điều hành.
pozcircuitboy

2
Phiên bản ngắn hơn của lệnh thứ hai:ip -4 a show eth0 | grep -Po 'inet \K[0-9.]*'
tukusejssirs

40

Nói chung, không bao giờ được đảm bảo rằng một hệ thống sẽ chỉ có một địa chỉ IP, ví dụ: bạn có thể có cả kết nối ethernet và wlan, và nếu bạn có kết nối VPN đang hoạt động thì bạn sẽ có một địa chỉ IP khác.

Linux

Trên Linux, hostname -Isẽ liệt kê (các) địa chỉ IP hiện tại. Việc dựa vào nó luôn chỉ trả về một địa chỉ IP rất có thể sẽ không hoạt động như mong đợi trong một số trường hợp (tức là liên kết VPN được kết nối), vì vậy một cách đáng tin cậy hơn sẽ là chuyển đổi kết quả thành một mảng và sau đó lặp lại các phần tử:

ips=($(hostname -I))

for ip in "${ips[@]}"
do
    echo $ip
done

OSX

Trên OSX, nếu bạn biết giao diện , bạn có thể sử dụng:

~$ ipconfig getifaddr en0
192.168.1.123

sẽ chỉ trả về địa chỉ IP.

Hoặc bạn có thể lặp lại các tên giao diện có thể có, bắt đầu bằng một hậu tố, tức là en:

for NUMBER in $(seq 0 5); do
    ip=`ipconfig getifaddr en$NUMBER`
    if [ -n "$ip" ]; then
        myip="$ip"
        break
    fi
done

echo $myip

Ngoài ra, việc lấy địa chỉ IP trở nên không xác định trong trường hợp cả kết nối cáp và wifi đều được thiết lập, khi một máy có nhiều giao diện ethernet hoặc khi có đường hầm VPN.

Lấy IP bên ngoài

Nếu bạn cần IP bên ngoài, thì bạn có thể truy vấn một dịch vụ chế độ văn bản, ví dụ: curl https://ipecho.net/plainsẽ trả về một IP bên ngoài văn bản thuần túy .

Và một cách nhanh hơn nữa để lấy IP bên ngoài là truy vấn một máy chủ DNS đã biết:

dig @ns1-1.akamaitech.net ANY whoami.akamai.net +short

làm thế nào để lấy địa chỉ ip LAN?
diEcho

17
hostname -I  

Lệnh này sẽ cung cấp cho bạn địa chỉ ip chính xác như bạn muốn trong Ubuntu.


so với số lượng đã tồn tại (và cao bình chọn) câu trả lời, tôi don không nghĩ rằng này câu trả lời sẽ bổ sung thêm bất kỳ giá trị ...
Mischa

4
cũng trên Centos hostname -I (chữ hoa i)
zzapper

1
điều này thực sự đã giúp tôi - chữ hoa được lưu ý 'i' là chìa khóa
ChronoFish

2
Tương tự, điều này thực hiện công việc hoàn hảo mà không cần công cụ bổ sung và không cần gọi mười lăm mã nhị phân liên tiếp để dọn dẹp đầu ra. Cảm ơn !
Ulrar

11

Trên các phiên bản Ubuntu mới nhất ( 14.04 - 16.04 ), lệnh này đã thực hiện thủ thuật cho tôi.

hostname -I | awk '{print $1}'

1
Từ trang hướng dẫn: "[...] Tùy chọn này liệt kê tất cả các địa chỉ được cấu hình trên tất cả các giao diện mạng. [...] Không đưa ra bất kỳ giả định nào về thứ tự của đầu ra". Câu cuối cùng cho bạn biết rằng print $1có thể có hoặc không cho bạn kết quả chính xác.
0 0

7

Nếu bạn có môi trường hạn chế, bạn có thể sử dụng lệnh này:

ip -4 addr show dev eth0 | grep inet | tr -s " " | cut -d" " -f3 | head -n 1

3
Hoặc thậm chí:ip -o -4 addr show dev eth0 | cut -d' ' -f7 | cut -d'/' -f1
Jose Alban

Vâng, bạn đã đúng. Nhưng hãy cẩn thận, nếu eth0 có nhiều hơn một địa chỉ IP, điều này sẽ hiển thị tất cả chúng.
caglar

bash-4.4 # ip -4 addr show dev eth0 | grep inet | tr -s "" | cắt -d "" -f3 | head -n 1 172.17.0.3/16 Vì vậy, không tốt với / 16
AndyGee

Thêm một người nữa cho vòng lặp: ip -4 addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1. Đối với cả v4 và v6:ip addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1
Sumit Murari

Nếu tên giao diện không được biết (hoặc khác nhau giữa các nền tảng) nhưng bạn tìm kiếm địa chỉ ip riêng thì thay vì ip -4 addr show eth0 | grep inetthực hiện:ip -4 addr show | grep 192
cyberbird

6

Để chỉ nhận địa chỉ IP trên Mac OS X, bạn có thể nhập lệnh sau:

ipconfig getifaddr en0

4

Lệnh ifconfigbị gỡ bỏ và bạn nên sử dụng iplệnh trên Linux.

Cũng ip asẽ cung cấp cho bạn phạm vi trên cùng một dòng với IP để dễ sử dụng hơn.

Lệnh này sẽ hiển thị cho bạn IP toàn cầu (bên ngoài) của bạn:

ip a | grep "scope global" | grep -Po '(?<=inet )[\d.]+'

Tất cả IPv4 (cũng là 127.0.0.1):

ip a | grep "scope" | grep -Po '(?<=inet )[\d.]+'

Tất cả IPv6 (cũng :: 1):

ip a | grep "scope" | grep -Po '(?<=inet6 )[\da-z:]+'

4

Chúng ta chỉ có thể sử dụng 2 lệnh (ifconfig + awk) để chỉ lấy IP (v4) mà chúng ta muốn như sau:

Trên Linux, giả sử lấy địa chỉ IP từ eth0giao diện, hãy chạy lệnh sau:

/sbin/ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'

Trên OSX, giả sử nhận địa chỉ IP từ en0giao diện, hãy chạy lệnh sau:

/sbin/ifconfig en0 | awk '/inet /{print $2}'

Để biết IP công cộng / bên ngoài của chúng tôi, hãy thêm chức năng này vào ~/.bashrc

whatismyip () {
    curl -s "http://api.duckduckgo.com/?q=ip&format=json" | jq '.Answer' | grep --color=auto -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"
}

Sau đó chạy, whatismyip


4

Để chỉ in địa chỉ IP của eth0, không có văn bản khác:

ifconfig eth0 | grep -Po '(?<=inet )[\d.]+'

Để xác định giao diện chính của bạn (vì nó có thể không phải là "eth0"), hãy sử dụng:

route | grep ^default | sed "s/.* //"

Hai dòng trên có thể được kết hợp thành một lệnh duy nhất như sau:

ifconfig `route | grep ^default | sed "s/.* //"` \
  | grep -Po '(?<=inet )[\d.]+'

3

Tôi muốn một cái gì đó đơn giản hoạt động như một bí danh Bash. Tôi thấy rằng điều đó phù hostname -Ihợp nhất với tôi (tên máy chủ v3.15). hostname -itrả về IP loopback, vì một số lý do, nhưng hostname -Icung cấp cho tôi IP chính xác cho wlan0 và không phải chuyển đầu ra thông qua grep hoặc awk. Một hạn chế là hostname -Isẽ xuất ra tất cả các IP, nếu bạn có nhiều hơn một IP.


2

Điều đó sẽ thực hiện thủ thuật trong máy Mac:

ping $(ifconfig en0 | awk '$1 == "inet" {print $2}')

Điều đó đã giải quyết ping 192.168.1.2trong máy của tôi.

Mẹo chuyên nghiệp : $(...)có nghĩa là chạy bất cứ thứ gì bên trong dấu ngoặc đơn trong một vỏ con và trả về giá trị đó.


2

Trong man hostnameđó còn có cách dễ dàng hơn là tự động loại trừ IP lặp lại và chỉ hiển thị danh sách được phân tách bằng dấu cách tất cả được gán cho địa chỉ ip máy chủ:

root@srv:~# hostname --all-ip-addresses
11.12.13.14 192.168.15.19 

root@srv:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
   inet6 ::1/128 scope host 
   valid_lft forever preferred_lft forever
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
  link/void 
  inet 11.12.13.14/32 scope global venet0:0
  inet 192.168.15.19/32 scope global venet0:1

2

Bạn cũng có thể sử dụng lệnh sau:

ip route | grep src

LƯU Ý: Điều này sẽ chỉ hoạt động nếu bạn có kết nối với Internet.


2

Vài câu trả lời dường như đang sử dụng phiên bản mới hơn iplệnh (thay thế cho ifconfig) vì vậy đây là một trong đó sử dụng ip addr, grepawkchỉ đơn giản là in các địa chỉ IPv4 gắn liền với wlan0giao diện:

ip addr show wlan0|grep inet|grep -v inet6|awk '{print $2}'|awk '{split($0,a,"/"); print a[1]}'

Mặc dù không phải là giải pháp nhỏ gọn hoặc lạ mắt nhất, nhưng nó (được cho là) ​​dễ hiểu (xem giải thích bên dưới) và sửa đổi cho các mục đích khác, chẳng hạn như lấy 3 octet cuối cùng của địa chỉ MAC như sau:

ip addr show wlan0|grep link/ether|awk '{print $2}'|awk '{split($0,mac,":"); print mac[4] mac[5] mac[6]}'

Giải thích: ip addr show wlan0 xuất ra thông tin được liên kết với giao diện mạng được đặt tên wlan0, tương tự như sau:

4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether dc:a6:32:04:06:ab brd ff:ff:ff:ff:ff:ff
    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::d340:5e4b:78e0:90f/64 scope link 
       valid_lft forever preferred_lft forever

Tiếp grep inetlọc ra các dòng không chứa "inet" (IPv4 và IPv6 cấu hình) và grep -v inet6bộ lọc ra các dòng còn lại mà làm chứa "inet6", mà nên kết quả trong một dòng như thế này:

    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0

Cuối cùng, thao tác đầu tiên awkgiải nén trường "172.18.18.1/24" và thao tác thứ hai xóa mặt nạ mạng, chỉ để lại địa chỉ IPv4.

Ngoài ra, tôi nghĩ điều đáng nói là nếu bạn đang viết kịch bản thì thường có nhiều công cụ phong phú hơn và / hoặc mạnh mẽ hơn để thu thập thông tin này, mà bạn có thể muốn sử dụng thay thế. Ví dụ: nếu sử dụng Node.js thì có ipaddr-linux, nếu sử dụng Ruby thì có linux-ip-parser, v.v.

Xem thêm /unix/119269/how-to-get-ip-address-using-shell-script


1

Sử dụng lệnh sau:

/sbin/ifconfig $(netstat -nr | tail -1 | awk '{print $NF}') | awk -F: '/inet /{print $2}' | cut -f1 -d ' '

1

Đây là phiên bản của tôi, trong đó bạn có thể chuyển một danh sách các giao diện, được sắp xếp theo mức độ ưu tiên:

getIpFromInterface()
{
    interface=$1
    ifconfig ${interface}  > /dev/null 2>&1 && ifconfig ${interface} | awk -F'inet ' '{ print $2 }' | awk '{ print $1 }' | grep .
}

getCurrentIpAddress(){
    IFLIST=(${@:-${IFLIST[@]}})
    for currentInterface in ${IFLIST[@]}
    do
        IP=$(getIpFromInterface  $currentInterface)
        [[ -z "$IP" ]] && continue
    echo ${IP/*:}
    return
    done
}

IFLIST=(tap0 en1 en0)
getCurrentIpAddress $@

Vì vậy, nếu tôi kết nối với VPN, Wifi và ethernet, địa chỉ VPN của tôi (trên giao diện tap0) sẽ được trả về. Tập lệnh hoạt động trên cả linux và osx và có thể nhận đối số nếu bạn muốn ghi đè IFLIST

Lưu ý rằng nếu bạn muốn sử dụng IPV6, bạn sẽ phải thay thế 'inet' bằng 'inet6'.


1

Tôi luôn cảm thấy cần điều này vào những thời điểm không ngờ nhất và, không thất bại, tìm kiếm các chủ đề như thế này trên SO. Vì vậy, tôi đã viết một tập lệnh đơn giản để lấy địa chỉ IPv4 qua netstat, được gọi là echoip- bạn có thể tìm thấy nó ở đây . Cơ sở dữ liệu cho các địa chỉ mạng trông như thế này, nó cũng lấy địa chỉ công khai của bạn từ ipecho.net:

IPV4='\d+(\.\d+){3}'
INTERFACES=`netstat -i | grep -E "$IPV4" | cut -d ' ' -f 1`
INTERFACE_IPS=`netstat -i | grep -oE "$IPV4"`

for i in "${!INTERFACES[@]}"; do
  printf "%s:\t%s\n" "${INTERFACES[$i]}" "${INTERFACE_IPS[$i]}"
done

Tập echoiplệnh cho kết quả như thế này:

$ echoip
public: 26.106.59.169
en0:    10.1.10.2

1

sử dụng tập lệnh một dòng này: ifconfig | grep "inet " | grep -v 127.0.0.1|awk 'match($0, /([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/) {print substr($0,RSTART,RLENGTH)}' mac & linux (được thử nghiệm trong ubuntu) cả hai đều hoạt động.


Rất vui vì nó hoạt động trên cả hai. Thêm vào đó bạn có thể gọi nó với ifconfig en0hoặc ifconfig eth1vv nếu bạn biết giao diện bạn muốn :)
jaygooby

1

Tôi không thích sử dụng awkvà như vậy trong các tập lệnh .. ipcó tùy chọn xuất ra trong JSON.

Nếu bạn bỏ qua $interfacethì bạn sẽ nhận được tất cả các địa chỉ ip:

ip -json addr show $interface | \
  jq -r '.[] | .addr_info[] | select(.family == "inet") | .local'

Tôi thích cách kết quả của lệnh ở định dạng cấu trúc json như lệnh ip. đây là một cách khác để lấy địa chỉ IP tương tự như trên bash ip -j addr show eth0 | jp "[0].addr_info[?family== 'inet'].local | [0]"
Jack Liu Shurui

0
ip addr|awk '/eth0/ && /inet/ {gsub(/\/[0-9][0-9]/,""); print $2}'

hiển thị tất cả các ips của bạn


0

Trên Redhat 64bit, điều này đã giải quyết được vấn đề cho tôi.

ifconfig $1|sed -n 2p|awk '{ print $2 }'|awk -F : '{ print $2 }'

hay này: curl ifconfig.me
Statham

0
#!/bin/sh
# Tested on Ubuntu 18.04 and Alpine Linux 
# List IPS of following network interfaces:
# virtual host interfaces
# PCI interfaces
# USB interfaces
# ACPI interfaces
# ETH interfaces
for NETWORK_INTERFACE in $(ls /sys/class/net -al | grep -iE "(/eth[0-9]+$|vif|pci|acpi|usb)" | sed -E "s@.* ([^ ]*) ->.*@\1@"); do 
    IPV4_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet addr[: ]+|inet[: ]+)' | sed -E "s@\s*(inet addr[: ]+|inet[: ]+)([^ ]*) .*@\2@")
    IPV6_ADDRESSES=$(ifconfig $NETWORK_INTERFACE | grep -iE '(inet6 addr[: ]+|inet6[: ]+)' | sed -E "s@\s*(inet6 addr[: ]+|inet6[: ]+)([^ ]*) .*@\2@")
    if [ -n "$IPV4_ADDRESSES" ] || [ -n "$IPV6_ADDRESSES" ]; then
        echo "NETWORK INTERFACE=$NETWORK_INTERFACE"
        for IPV4_ADDRESS in $IPV4_ADDRESSES; do 
            echo "IPV4=$IPV4_ADDRESS"
        done
        for IPV6_ADDRESS in $IPV6_ADDRESSES; do 
            echo "IPV6=$IPV6_ADDRESS"
        done
    fi
done

0

Khi tra cứu địa chỉ IP bên ngoài của bạn trên máy chủ NAT, khá nhiều câu trả lời đề xuất sử dụng các phương pháp dựa trên HTTP như ifconfig.me:

$ curl ifconfig.me/ip

Trong những năm qua, tôi đã thấy nhiều trang web này đến và đi, tôi thấy phương pháp dựa trên DNS này mạnh mẽ hơn:

$ dig +short myip.opendns.com @resolver1.opendns.com

Tôi có bí danh tiện dụng này trong ~/.bashrc:

alias wip='dig +short myip.opendns.com @resolver1.opendns.com'

0

Hai cách này đã hiệu quả với tôi:

Để lấy địa chỉ IP của giao diện eth0 của bạn. Thay thế eth0 trong ví dụ dưới đây bằng tên giao diện của bạn. ifconfig eth0 | grep -w "inet" | tr -s " " | cut -f3 -d" "

Sử dụng tên máy chủ: Điều này sẽ cung cấp cho bạn inet tức là Địa chỉ IP của địa chỉ của bạn. sử dụng -Tôi sẽ cung cấp cho bạn giá trị inet của tất cả các giao diện bất cứ khi nào giá trị này hiện diện.

hostname -i


-1
curl ifconfig.co 

Điều này chỉ trả về địa chỉ ip của hệ thống của bạn.


1
Điều này yêu cầu kết nối internet hoạt động và sẽ trả về địa chỉ IP hiển thị công khai của bạn, địa chỉ này có thể là địa chỉ bạn muốn hoặc có thể không.
JLH

-2

Tôi sẽ Sử dụng Hostname -Lđể chỉ lấy IP để sử dụng như một biến trong tập lệnh.


Có lẽ bạn đang cố nói hostname -ihoặc hostname -I?
JLH

user@linux:~$ Hostname -L -bash: Hostname: command not found user@linux:~$ 1. Vốn Hlà sai 2. Không như vậy-L
Sabrina
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.