Яка термінальна команда отримати лише IP-адресу та нічого іншого?


118

Я намагаюся використовувати лише IP-адресу (inet) як параметр у написаному сценарієм.

Чи є простий спосіб в терміналі unix отримати лише IP-адресу, а не переглядати ifconfig?


Так, або будь-який інший унікальний ідентифікатор машини, який я думаю.
Мейсон

1
ви отримуєте недійсний варіант на ім'я хоста -i?
Кен

4
ім'я хоста не настільки надійне, як ifconfig
joel

2
Джоел має рацію, спеціально ви там, де говорите про MAC OS, а потім про Ubuntu
zackaryka

2
Переглядаючи відповіді нижче, майте на увазі, що з результатом роботи ip -o addressнабагато простіше, ніж з результатом ip address.
jlh

Відповіді:


177

Ви можете написати сценарій, який повертає лише IP, наприклад:

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

Для MAC:

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

Або для системи Linux

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

hostname -i # Debian

4
hostname -iна моєму повертається:::1 127.0.1.1 192.168.1.100
Книга Зевса

1
На Debian я отримав лише один ip. Тому використання hostnameне є портативним.
Тимофей Столбов

1
У ньому йдеться про те, що -i та -i обидва є незаконними варіантами
Мейсон

3
Підсумовуючи: перший метод залежить від адаптера, який не завжди є однаковим. Другий для мене показує дві IP-адреси, а останні два не працюють на Mac.
Метт

4
ifconfig тут застарілий і ненадійний, наприклад, grep виходить з ладу на debian 9 (stretch), оскільки він більше не видає "inet addr: 172.17.0.4", він видає лише "inet 172.17.0.4". Використовуйте натомість "ip", як описано в stackoverflow.com/a/26694162/72717 .
джамшид

61

Це дасть вам усі інтерфейси IPv4, включаючи цикл 127.0.0.1:

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

Це покаже лише eth0:

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

І таким чином ви можете отримати адреси IPv6:

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

Тільки eth0IPv6:

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

grep -oPЗазнає невдачі на BusyBox v1.24.1: невірний варіант - P
Pro резервного копіювання

1
grep не встановлюється майже на кожному докерському конатинері для prod. Отже, хоча це все хороші команди, вони не будуть корисні для контейнерів :-(
AndyGee

1
Найкраща відповідь для мого конкретного випадку. Вам потрібен -Pперемикач для регулярних виразів Perl або інакше ми не можемо використовувати (?<=inet\s)маркер lookbehind . Ви можете отримати подібний результат, запустивши grep -oe 'inet [0-9\.]\+'або , grep -oe 'inet6 [0-9a-f:]\+'але таким чином , я не можу позбутися від першого слова. У man grepповідомленнях SuSE цей -Pпрапор є експериментальним.
Хорхе Беллон

Це найкраща відповідь. ifconfig застарілий уже кілька років на більшості ОС.
pozcircuitboy

2
Скорочена версія другої команди:ip -4 a show eth0 | grep -Po 'inet \K[0-9.]*'
tukusejssirs

40

Як правило, ніколи не гарантується, що система матиме лише одну IP-адресу, наприклад, ви можете мати як Ethernet, так і wlan-з'єднання, а якщо у вас активне VPN-з'єднання, у вас буде ще одна IP-адреса.

Linux

У Linux hostname -Iбуде вказано поточні IP-адреси. Покладаючись на це, що завжди повертається лише одна IP-адреса, швидше за все, не працюватиме так, як очікувалося в деяких сценаріях (тобто, посилання VPN піднялася), тому більш надійним способом було б перетворення результату в масив, а потім циклічне переключення на елементи:

ips=($(hostname -I))

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

OSX

На OSX, якщо ви знаєте інтерфейс , ви можете використовувати:

~$ ipconfig getifaddr en0
192.168.1.123

який поверне лише IP-адресу.

Або ви можете переглядати можливі імена інтерфейсу, починаючи з суфіксу, тобто en:

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

echo $myip

Крім того, отримання IP-адреси стає недетермінованою, якщо встановлено кабельне та Wi-Fi-з'єднання, коли машина має більше одного інтерфейсу Ethernet або коли є тунелі VPN.

Отримання зовнішнього IP-адреси

Якщо вам потрібен зовнішній IP-код, ви можете запитувати послугу текстового режиму, наприклад curl https://ipecho.net/plain, повертає звичайний текстовий зовнішній IP-адресу.

А ще швидший спосіб отримати зовнішній IP - це запит на відомий DNS-сервер:

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

як отримати ip-адресу LAN?
diEcho

17
hostname -I  

Ця команда дасть вам точну ip адресу, як ви хочете в Ubuntu.


в порівнянні з кількістю вже існуючих (і високо оцінених) відповідей, я не думаю, що ця відповідь не додасть ніякої цінності ...
Mischa

4
також на ім'я хосту Centos -I (верхній регістр i)
zzapper

1
це насправді допомогло мені - відмічена велика літера «я» була ключовою
ChronoFish

2
Це також робить цю роботу ідеально без зайвих інструментів і не потрібно викликати п'ятнадцять двійкових файлів поспіль, щоб очистити вихід. Дякую !
Ульрар

11

У останніх версіях Ubuntu ( 14.04 - 16.04 ) ця команда зробила для мене трюк.

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

1
На сторінці керівництва: "[...] Ця опція перераховує всі налаштовані адреси на всіх мережевих інтерфейсах. [...] Не робіть жодних припущень щодо порядку виводу". Останнє речення говорить про те, що print $1може чи не може дати тобі правильний результат.
0 0

7

Якщо у вас обмежене середовище, ви можете використовувати цю команду:

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

3
Або навіть:ip -o -4 addr show dev eth0 | cut -d' ' -f7 | cut -d'/' -f1
Хосе Альбан

Так, ти маєш рацію. Але будьте обережні, якщо eth0 має більше однієї IP-адреси, це показує всі вони.
caglar

bash-4.4 # ip -4 addr show dev eth0 | grep inet | tr -s "" | вирізати -d "" -f3 | head -n 1 172.17.0.3/16 Так не добре з / 16
AndyGee

Додавання одного більше до петлі: ip -4 addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1. Для обох v4 і v6:ip addr show eth0 | grep inet | awk '{print $2}' | cut -d'/' -f1
Sumit Мурари

Якщо назва інтерфейсу не відома (або відрізняється між платформами), але ви шукаєте приватну ip-адресу, то замість цього ip -4 addr show eth0 | grep inetробіть:ip -4 addr show | grep 192
cyberbird

6

Щоб отримати лише IP-адресу в Mac OS X, ви можете ввести таку команду:

ipconfig getifaddr en0

4

Команда ifconfigзастаріла, і ви повинні використовувати ipкоманду в Linux.

Також ip aнадасть вам сферу застосування в тій же лінії, що і IP, щоб було простіше у використанні.

Ця команда покаже вам ваш глобальний (зовнішній) IP:

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

Усі IPv4 (також 127.0.0.1):

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

Усі IPv6 (також :: 1):

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

4

Ми можемо просто використовувати лише 2 команди (ifconfig + awk), щоб отримати тільки IP (v4), який ми хочемо так:

У Linux, припускаючи отримання IP-адреси з eth0інтерфейсу, запустіть таку команду:

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

В OSX, припускаючи отримання IP-адреси з en0інтерфейсу, запустіть таку команду:

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

Щоб знати наш громадський / зовнішній IP, додайте цю функцію в ~/.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"
}

Тоді біжи, whatismyip


4

Щоб надрукувати лише IP-адресу eth0без іншого тексту:

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

Щоб визначити ваш основний інтерфейс (оскільки він може бути не "eth0"), використовуйте:

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

Вищеописані два рядки можна об'єднати в одну команду, як це:

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

3

Я хотів чогось простого, що працювало б псевдонімом Баша. Я виявив, що hostname -Iнайкраще працює для мене (ім'я хоста v3.15). hostname -iз певних причин повертає loopback IP, але hostname -Iдає мені правильний IP-код для wlan0 і без необхідності передавати вихід через grep або awk. Недолік - це hostname -Iвиведення всіх IP-адрес, якщо у вас їх більше.


2

Це зробить трюк в Mac:

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

Це вирішено ping 192.168.1.2в моїй машині.

Підказка : $(...)означає запустити все, що знаходиться в круглих дужках, в підклітині і повернути це як значення.


2

В man hostnameє ще більш простий спосіб , який автоматично за винятком петлевий IP і показує тільки список розділених пробілами всі призначені для хоста IP - адреси:

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

Ви також можете використовувати таку команду:

ip route | grep src

ПРИМІТКА. Це буде працювати лише за наявності підключення до Інтернету.


2

Кілька відповідей , по всій видимості, використовує новішу ipкоманду (заміна для ifconfig) , тому тут є один , який використовує ip addr, grepі awkпросто надрукувати адресу IPv4 , пов'язаний з wlan0інтерфейсом:

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

Хоча це не найбільш компактне чи вигадливе рішення, його (напевно) легко зрозуміти (див. Пояснення нижче) та змінити для інших цілей, наприклад отримання останніх 3 октетів такої MAC-адреси:

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

Пояснення: ip addr show wlan0 виводить інформацію, пов’язану з названим мережевим інтерфейсом wlan0, який повинен бути подібним до цього:

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

Далі grep inetфільтри з ліній , які не містять «інет» (IPv4 та IPv6 конфігурації) і grep -v inet6фільтри з інших рядків , які роблять містити «inet6», що має привести в одну лінію , як цей:

    inet 172.18.18.1/24 brd 172.18.18.255 scope global noprefixroute wlan0

Нарешті, перший awkвитягує поле "172.18.18.1/24", а другий видаляє скорочення мережевої маски, залишаючи лише IPv4-адресу.

Крім того, я думаю, що варто згадати, що якщо ви розробляєте сценарії, то для отримання цієї інформації часто існує багато багатших та / або більш надійних інструментів, які ви, можливо, захочете використовувати натомість. Наприклад, якщо використовується Node.js, є ipaddr-linux, якщо використовується Ruby, є linux-ip-parserі т.д.

Дивіться також /unix/119269/how-to-get-ip-address-using-shell-script



1

Ось моя версія, в якій ви можете передати список інтерфейсів, упорядкованих за пріоритетом:

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 $@

Тож якщо я підключений до VPN, Wifi та Ethernet, повернеться моя VPN-адреса (в інтерфейсі tap0). Сценарій працює як на Linux, так і на OSX, і може приймати аргументи, якщо ви хочете замінити IFLIST

Зауважте, що якщо ви хочете використовувати IPV6, вам доведеться замінити "inet" на "inet6".


1

Мені завжди потрібне це в найнесподіваніші моменти, і, безумовно, я шукаю такі теми в SO. Тому я написав простий скрипт, щоб отримати адреси IPv4 через netstat, званий echoip- його можна знайти тут . Баш для мережевих адрес виглядає приблизно так, він також отримує вашу публічну адресу від 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

echoipСценарій дає такий висновок:

$ echoip
public: 26.106.59.169
en0:    10.1.10.2

1

використовувати цей однорядковий сценарій: 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 (тестується в ubuntu) обидва працює.


Приємно, що працює на обох. Крім того, ви можете зателефонувати за допомогою ifconfig en0і ifconfig eth1т.
Д.,

1

Я вважаю за краще не використовувати awkі таке в скриптах .. ipмає можливість виводити в JSON.

Якщо ви залишаєтесь, $interfaceви отримуєте всі ip адреси:

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

Мені подобається, як результат команди в структурному форматі json, як команда ip. ось ще один спосіб отримати IP-адресу, подібну вище, bash ip -j addr show eth0 | jp "[0].addr_info[?family== 'inet'].local | [0]"
Джек Лю Шуруй,

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

показує всі ваші ips



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

Під час пошуку зовнішньої IP-адреси на NATed хості, досить багато відповідей пропонують використовувати методи на основі HTTP, ifconfig.meнаприклад:

$ curl ifconfig.me/ip

Протягом багатьох років я бачив, як багато з цих сайтів приходять і переходять, я вважаю цей метод на основі DNS більш надійним:

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

У мене цей зручний псевдонім ~/.bashrc:

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

0

Ці два способи працювали для мене:

Щоб отримати IP-адресу вашого інтерфейсу eth0. Замініть eth0 у наведеному нижче прикладі на ім'я інтерфейсу. ifconfig eth0 | grep -w "inet" | tr -s " " | cut -f3 -d" "

Використання імені хоста: це дасть вам інет, тобто IP-адресу вашого ето. використовуючи-я дам вам значення inet всіх інтерфейсів, де б це значення не було.

hostname -i


-1
curl ifconfig.co 

Це повертає лише ip-адресу вашої системи.


1
Для цього потрібне робоче з'єднання з Інтернетом і поверне вашу публічно видиму IP-адресу, яка може бути або не бути такою, яку ви хочете.
jlh

-2

Я хотів би використовувати, Hostname -Lщоб отримати просто IP для використання в якості змінної в сценарії.


Можливо, ви намагалися сказати hostname -iчи hostname -I?
jlh

user@linux:~$ Hostname -L -bash: Hostname: command not found user@linux:~$ 1. Капітал Hпомиляється 2. Ніякого такого-L
Сабріна
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.