Какая команда терминала получить только IP-адрес и ничего больше?


118

Я пытаюсь использовать только IP-адрес (inet) в качестве параметра в написанном мной скрипте.

Есть ли в терминале unix простой способ получить только IP-адрес, а не просматривать ifconfig?


Да, или любой другой уникальный идентификатор машины, я полагаю.
Мейсон

1
у вас неверная опция для имени хоста -i?
Кен

4
имя хоста не так надежно, как ifconfig
Джоэл

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
Book Of Zeus

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 .
jamshid

61

Это даст вам все интерфейсы IPv4, включая loopback 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 не устанавливается почти на всех docker conatiner for prod. Так что, хотя это все хорошие команды, они не будут полезны для контейнеров :-(
AndyGee

1
Лучший ответ для моего конкретного случая. Вам нужен -Pпереключатель для регулярных выражений Perl, иначе мы не сможем использовать (?<=inet\s)маркер просмотра назад . Вы можете получить аналогичный результат, запустив 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

41

Как правило, никогда не гарантируется, что система будет иметь только один 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.


по сравнению с количеством уже существующих (и получивших большое количество голосов) ответов, я не думаю, что этот ответ добавит какую-либо ценность ...
Миша

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

1
это действительно помогло мне - отмеченная прописная буква «i» была ключевой
ChronoFish

2
То же самое, это отлично справляется со своей задачей без дополнительных инструментов и без необходимости вызывать пятнадцать двоичных файлов подряд для очистки вывода. Спасибо !
Ulrar

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 | тр-с "" | вырезать -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

Я хотел что-то простое, что работало бы как псевдоним Bash. Я обнаружил, что это hostname -Iработает лучше всего для меня (имя хоста v3.15). hostname -iпо какой-то причине возвращает 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, Wi-Fi и Ethernet, мой адрес VPN (на интерфейсе tap0) будет возвращен. Скрипт работает как в Linux, так и в OSX, и может принимать аргументы, если вы хотите переопределить IFLIST.

Обратите внимание: если вы хотите использовать IPV6, вам придется заменить inet на inet6.


1

Мне это всегда нужно в самые неожиданные моменты, и я обязательно начинаю искать подобные темы на SO. Итак, я написал простой скрипт для получения адресов IPv4 через netstat, который называется echoip- вы можете найти его здесь . Bash для сетевых адресов выглядит так, он также получает ваш публичный адрес с 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т. Д., Если знаете, какой интерфейс вам нужен :)
jaygooby

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

На 64-битной версии Redhat это решило для меня проблему.

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

или это: curl ifconfig.me
Стэтхэм

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-адреса на хосте с NAT многие ответы предлагают использовать методы на основе 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" "

Использование имени хоста: это даст вам inet, то есть IP-адрес вашего etho. использование -I даст вам значение 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.