Какой самый краткий способ преобразовать имя хоста в IP-адрес в скрипте Bash? Я использую Arch Linux .
linux
bash
networking
dns
Евгений Ярмаш
источник
источник
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
ответ где-то там, внизу. Он самый простой, не требует дополнительных пакетов и его легче анализировать из скрипта Bash.getent hosts somehost
, когда работает это время наsomehost
произведет IPv6 - адрес , который отличается от того, как и большинства других инструментов (ping
,ssh
по крайней мере) разрешения имен, и ломает некоторые вещи. Используйтеahosts
вместоhosts
.ahostsv4
) или IPv6 (ahostsv6
)? Лично я не нахожу ничего плохого в неопределенном запросе, возвращающем IPv6. Ваш код должен быть подготовлен. IPv6 существует уже более 20 лет.hosts
, и до сих пор 4 человека проголосовали против комментария vinc17, выражающего боль, вызванную «неожиданно IPv6». Подготовка к IPv6 не всегда является проблемой: многим программам нужен способ определить, относятся ли два имени / адреса к одному и тому же хосту. Они могут либо использовать простое сопоставление строк, либо они должны много знать о сети, чтобы найти «верный» ответ. Последнее является минным полем, поэтому многие сторонние программы и системы, которые я не могу контролировать, используют первые.Ответы:
Вы можете использовать
getent
, что идет сglibc
(так что вы почти наверняка имеете его в Linux). Это решается с помощью gethostbyaddr / gethostbyname2, а также проверяет/etc/hosts
/ NIS / etc:Или, как сказал Хайнци ниже, вы можете использовать
dig
этот+short
аргумент (запрашивает DNS-серверы напрямую, не просматривает/etc/hosts
/ NSS / и т. Д.):Если
dig +short
недоступно, любое из следующего должно работать. Все они обращаются к DNS напрямую и игнорируют другие средства разрешения:Если вы хотите напечатать только один IP, добавьте
exit
команду вawk
рабочий процесс.источник
host www.google.com
,dig +short www.google.com
,host ipv6.google.com
,dig +short ipv6.google.com
,host www.facebook.com
,dig +short www.facebook.com
.host
может быть тайм-аут и ничего не возвращает. Для некоторых доменовdig +short
может возвращать псевдоним домена в первой строке. Итак, чтобы убедиться, что выводом является адрес IPv4, используйтеdig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1
.getent hosts <host>
некорректно, например, оно может дать адрес IPv6, а IPv6 не работает. Правильное решение - использоватьgetent ahosts <host>
оба IPv6 и IPv4, если это необходимо.С
host
из пакета dnsutils :( Исправлено имя пакета в соответствии с комментариями. Как примечание, другие дистрибутивы имеют
host
в разных пакетах: Debian / Ubuntu bind9-host , openSUSE bind-utils , Frugalware bind .)источник
host
работал хорошо, спасибоhost
в виду, что иногда возвращает многострочный вывод (в случае перенаправления), вы захотите,host unix.stackexchange.com | tail -n1
если вы просто хотите строку с IP-адресом.host
является инструментом DNS (аналогичноnslookup
), поэтому он ищет хосты только в DNS, а не, например, в/etc/hosts
. Так что это НЕ ответ на вопрос ОП.У меня есть инструмент на моей машине, который, кажется, делает эту работу. Страница man показывает, что, похоже, она поставляется с mysql ... Вот как вы можете ее использовать:
Возвращаемое значение этого инструмента отличается от 0, если имя хоста не может быть разрешено:
ОБНОВЛЕНИЕ На fedora, это идет с mysql-сервером:
Я думаю, это создаст странную зависимость для вашего сценария ...
источник
getent
Как подробно описано в другом ответе, он также просматривает / etc / hosts и поставляется с glibc, поэтому не зависит от системы Linux.Следующая команда using
dig
позволяет вам читать результат напрямую без каких-либо sed / awk / etc. магия:dig
также входит вdnsutils
комплект.Примечание :
dig
имеет возвращаемое значение0
, даже если имя не может быть разрешено. Таким образом, вам нужно проверить, пустой ли вывод, вместо проверки возвращаемого значения:Примечание 2 : Если имя хоста имеет несколько IP-адресов (попробуйте
debian.org
, например), все они будут возвращены. Эта «проблема» затрагивает все инструменты, упомянутые в этом вопросе:источник
источник
ahosts
,ahostsv4
,ahostsv6
сgetent
.cut
не для гетентов, которые используют\t
для разделения столбцов. Это дело Соляриса.cut
без-d
(по умолчанию\t
это разделитель). В Linux это пробелы, поэтому строка выше работает.Представленные решения в основном работают в более простом случае: имя хоста напрямую разрешается в один адрес IPv4. Это может быть единственный случай, когда вам нужно разрешить имена хостов, но если нет, то ниже приводится обсуждение некоторых случаев, которые вам, возможно, придется обработать.
Крис Даун и Хайнци кратко обсудили случай, когда имя хоста разрешается для более чем одного IP-адреса. В этом случае (и других ниже) базовые сценарии в предположении, что имя хоста напрямую разрешает один IP-адрес, могут сломаться. Ниже приведен пример разрешения имени хоста более чем на один IP-адрес:
А что есть
www.l.google.com
? Это где случай псевдоним должен быть введен. Давайте проверим пример ниже:Таким образом,
www.google.com
он не разрешается напрямую по IP-адресам, а по псевдониму, который сам по себе разрешает несколько IP-адресов. Для получения дополнительной информации об псевдонимах, проверьте здесь . Конечно, возможен случай, когда псевдоним имеет один IP-адрес, как показано ниже:Но можно ли связывать псевдонимы? Ответ да:
Я не нашел ни одного примера, где имя хоста преобразуется в псевдоним, который не преобразуется в IP-адрес, но я думаю, что это может произойти.
Более чем несколько IP-адресов и псевдонимов, есть ли другие особые случаи ... как насчет IPv6? Вы можете попробовать:
Где имя хоста
ipv6.google.com
является именем хоста только для IPv6. А как насчет имен хостов с двумя стеками:Опять же, что касается IPv6, если ваш хост - только IPv4, вы все равно можете разрешать адреса IPv6 (протестировано на WinXP только для IPv4, а с ipv6.google.com вы можете попробовать его в Linux). В этом случае разрешение завершается успешно, но проверка связи не выполняется с неизвестным сообщением об ошибке хоста . Это может быть случай, когда ваш сценарий не работает.
Я надеюсь, что эти замечания были полезны.
источник
host
даже нет «адреса» для моих ящиков.Чтобы избежать проблемы с псевдонимами и всегда получать один IP-адрес, готовый к использованию:
источник
работает без зависимостей в других системах (и для хостов, указанных в / etc / hosts)
источник
ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
работает для объявлений внутри/etc/hosts
тоже ... и это инструмент идти к для всех видов системных баз данных (PASSWD, группы, псевдонимов, услуги).Просто, но полезно:
getent ahostsv4 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent ahostsv6 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent hosts google.de | head -n 1 | cut -d ' ' -f 1
Все команды разрешают IP-адрес, если хост все еще существует. Если хост указывает на CNAME, он также получит IP в этом случае.
Первая команда возвращает разрешенный адрес IPv4
Вторая команда возвращает разрешенный адрес IPv6
Третья команда вернет владельцу предпочтительный адрес, который может быть IPv4 или IPv6.
источник
host
, как это требует установкиbindutils
Вот небольшой вариант
ping
подхода, который учитывает «неизвестный хост» (путем передачи через stderr) и использует,tr
чтобы избежать использованияsed
регулярных выражений:В случае, если важно получить выходное значение, будет работать следующее (хотя и менее изящное):
источник
Чтобы завершить ответ Криса Дауна и обратиться к комментариям jfgagne относительно (возможно, связанных) псевдонимов, вот решение, которое:
/etc/hosts
файл (в моем случае я этого не хотел); чтобы запросить его, решение Python от dbernt идеально подходит)не использует awk / sed
Всегда возвращает первый IP-адрес или пустую строку, если не решен. с версией раскопок:
источник
источник
Я хотел бы добавить это как комментарий к Эндрю МакГрегору Re: ping. Однако это не позволило бы мне, поэтому мне нужно добавить это в качестве другого ответа. (Если кто-то может переместить это в комментарий, не стесняйтесь.)
Это еще один вариант, только с использованием ping и grep:
grep -E
для расширенного регулярного выражения иgrep -o
для возврата только соответствующей части. само регулярное выражение ищет одну или несколько цифр ([0-9]+
) и, необязательно, точку (\.?
) четыре раза ({4}
)источник
Вы можете использовать
host
:источник
вот рецепт Bash, который я приготовил, используя ответы других людей - сначала пробует
/etc/hosts
, потом возвращается к nslookup:источник
getent hosts
это не просто поиск в / и т.д. / хостов - это полный на DNS-разрешения вызова gethostbyaddr (3) , и это очень маловероятно , чтобы потерпеть неудачу в случае , еслиdig
удастся. Смотрите man-страницу для getent .getent
остается моим любимым, хотя мне тоже нравитсяdig +short
было решение, которое я нашел без DNS-сервера
источник
Может быть, не самый лаконичный, но кажется надежным и эффективным:
Это выдаст один IPv4 IP, а также вернет
1
в случае сбоя, маскируя вывод stderr.Вы можете использовать это так:
Если вы хотите вместо этого адрес IPv6, просто замените
-4
на-6
.источник
dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'
источник
1 строка разрешает список имен хостов
источник
Я делаю это все время на моем Mac, которого нет
getent
.ping
похоже на взлом. Я хотел бы принять/etc/hosts
во внимание также.Итак, я написал глупую оболочку для
dns.lookup
вас, у которых установлен Node.js для предоставления CLI:источник
копать слишком медленно, nslookup намного быстрее
источник
Я не знаю самый простой способ для bash-скрипта, но если вы хотите разрешить имя хоста и посмотреть, работает ли хост, используйте
ping
!Будет ли
ping
хост один раз и разрешить имя хоста по IP-адресу.источник
Да, ответов уже много, но решение с использованием perl отсутствует:
В скрипте bash это можно использовать так:
Модули, используемые здесь, являются основными модулями, поэтому должны быть доступны везде без установки с CPAN.
источник
perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null
намного чище но никто, кроме нас двоих, не использует pörl, все остальные, конечно, используют Pascal Script.Can't call method "addr" on an undefined value
не совсем лучшее сообщение об ошибке, но может дать подсказку о проблеме.источник
print
следует использовать вместоp
.эта команда покажет IP-адрес (перенастроит домен на IP)
источник
Помимо вышеприведенного решения, вы можете перевести несколько имен хостов в ip через скрипт ниже, единственная зависимость - это команда «ping» в ядре Unix:
источник