Jaki jest najbardziej zwięzły sposób rozwiązania nazwy hosta na adres IP w skrypcie Bash? Używam Arch Linux .
linux
bash
networking
dns
Eugene Yarmash
źródło
źródło
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
odpowiedź jest gdzieś u dołu. Jest najprostszy, nie wymaga żadnych dodatkowych pakietów i jest łatwiejszy do analizy ze skryptu Bash.getent hosts somehost
, gdy uruchomienie tego czasu nasomehost
będzie produkować adres IPv6 , który różni się od tego, jak większość innych narzędzi (ping
,ssh
przynajmniej) rozpoznawania nazw i łamie pewne rzeczy. Użyjahosts
zamiasthosts
.ahostsv4
) lub IPv6 (ahostsv6
)? Osobiście nie znajduję nic złego w nieokreślonym żądaniu zwracającym IPv6. Twój kod powinien być przygotowany. IPv6 istnieje już od ponad 20 lat.hosts
, a jak dotąd 4 osoby pozytywnie oceniły komentarz vinc17 wyrażający ból spowodowany przez „nagle IPv6”. Przygotowanie do IPv6 nie zawsze jest problemem: wiele programów potrzebuje sposobu, aby ustalić, czy dwie nazwy / adresy odnoszą się do tego samego hosta. Mogą albo użyć prostego dopasowania łańcucha, albo muszą dużo wiedzieć o sieci, aby znaleźć „prawdziwą” odpowiedź. To ostatnie jest polem minowym, więc wiele programów i systemów innych firm - nad którymi nie mam kontroli - używa tych pierwszych.Odpowiedzi:
Możesz użyć
getent
, który pochodzi zglibc
(więc prawie na pewno masz go w systemie Linux). To rozwiązuje się za pomocą gethostbyaddr / gethostbyname2, a więc również sprawdzi/etc/hosts
/ NIS / etc:Albo, jak powiedział Heinzi poniżej, można korzystać
dig
z+short
argumentu (serwerów DNS zapytań bezpośrednio, nie patrzy w/etc/hosts
/ etc / NSS):Jeśli
dig +short
jest niedostępny, jeden z poniższych powinien działać. Wszystkie te zapytania DNS bezpośrednio i ignorują inne sposoby rozwiązania:Jeśli chcesz wydrukować tylko jeden adres IP, dodaj
exit
polecenie doawk
przepływu pracy.źródło
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
może zostać przekroczony limit czasu i nic nie zwraca. W przypadku niektórych domendig +short
może zwracać alias domeny w pierwszym wierszu. Tak więc, aby upewnić się, że wyjście to adres IPv4, użyjdig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1
.getent hosts <host>
jest nieprawidłowe, ponieważ może na przykład dać adres IPv6, podczas gdy IPv6 nie działa. Prawidłowym rozwiązaniem jestgetent ahosts <host>
wypróbowanie zarówno IPv6, jak i IPv4 w razie potrzeby.Wraz
host
z dnsutils opakowaniu:( Poprawiona nazwa pakietu zgodnie z komentarzami. Uwaga: inne dystrybucje mają
host
różne pakiety: Debian / Ubuntu bind9-host , openSUSE bind-utils , Frugalware bind .)źródło
host
działało dobrze, dziękihost
czasami zwraca wyjście wieloliniowe (w przypadku przekierowań), będziesz chciał,host unix.stackexchange.com | tail -n1
jeśli chcesz tylko linię z adresem IP.host
jest narzędziem DNS (podobnym donslookup
), więc wyszukuje tylko hosty w DNS, a nie np/etc/hosts
. Więc to NIE jest odpowiedź na pytanie OP.Mam na komputerze narzędzie, które wydaje się wykonywać tę pracę. Strona podręcznika pokazuje, że wydaje się, że pochodzi z mysql ... Oto jak możesz go użyć:
Zwracana wartość tego narzędzia różni się od 0, jeśli nie można rozwiązać nazwy hosta:
AKTUALIZACJA W Fedorze jest dostarczany z serwerem mysql:
Myślę, że stworzyłoby to dziwną zależność dla twojego skryptu ...
źródło
getent
, jak szczegółowo opisano w drugiej odpowiedzi, również przegląda / etc / hosts i jest wyposażony w glibc, więc nie ma zależności od systemu Linux.Poniższa komenda
dig
pozwala na odczyt wyniku bezpośrednio bez sed / awk / etc. magia:dig
jest również zawarty wdnsutils
pakiecie.Uwaga :
dig
ma wartość zwracaną0
, nawet jeśli nazwy nie można rozwiązać. Dlatego musisz sprawdzić, czy dane wyjściowe są puste, zamiast sprawdzać wartość zwracaną:Uwaga 2 : Jeśli nazwa hosta ma wiele adresów IP (
debian.org
na przykład spróbuj ), wszystkie zostaną zwrócone. Ten „problem” dotyczy wszystkich narzędzi wymienionych do tej pory w tym pytaniu:źródło
źródło
ahosts
,ahostsv4
,ahostsv6
zgetent
.cut
nie będzie dla getent, które używają\t
do oddzielania kolumn. Tak jest w przypadku Solaris.cut
bez-d
(domyślnie\t
jako separator). W Linuksie są to spacje, więc powyższa linia działa.Dotychczasowe rozwiązania działają głównie w prostszym przypadku: nazwa hosta jest tłumaczona bezpośrednio na pojedynczy adres IPv4. Może to być jedyny przypadek, w którym musisz rozwiązać nazwy hostów, ale jeśli nie, poniżej znajduje się dyskusja na temat niektórych spraw, które mogą być konieczne.
Chris Down i Heinzi krótko omówili przypadek, w którym nazwa hosta rozwiązuje się na więcej niż jednym adresie IP. W tym przypadku (i innych poniżej) podstawowe skrypty przy założeniu, że nazwa hosta bezpośrednio rozpoznaje pojedynczy adres IP, mogą ulec uszkodzeniu. Poniżej przykład z nazwą hosta tłumaczącą się na więcej niż jeden adres IP:
Ale co to jest
www.l.google.com
? W tym miejscu należy wprowadzić przypadek aliasu . Sprawdźmy poniższy przykład:Nie
www.google.com
dotyczy to bezpośrednio adresów IP, ale alias, który sam przekształca się w wiele adresów IP. Aby uzyskać więcej informacji na temat aliasów, sprawdź tutaj . Oczywiście możliwy jest przypadek, w którym alias ma jeden adres IP, jak pokazano poniżej:Ale czy można powiązać aliasy? Odpowiedź brzmi tak:
Nie znalazłem żadnego przykładu, w którym nazwa hosta jest tłumaczona na alias, który nie jest rozpoznawany na adres IP, ale myślę, że może tak być.
Więcej niż wiele adresów IP i aliasów, czy są jakieś inne specjalne przypadki ... a co z IPv6? Możesz spróbować:
Gdzie
ipv6.google.com
nazwa hosta to nazwa hosta tylko IPv6. Co z nazwami hostów z dwoma stosami:Znowu o IPv6, jeśli twój host jest tylko IPv4, nadal możesz rozwiązać adresy IPv6 (testowane na WinXP tylko dla IPv4 i na ipv6.google.com, możesz wypróbować to na Linuksie). W takim przypadku rozdzielczość się powiedzie, ale ping nie powiedzie się z komunikatem o błędzie nieznanego hosta . Może to być przypadek, w którym skrypt nie działa.
Mam nadzieję, że te uwagi były przydatne.
źródło
host
nawet nie podaje „ma adres” moich skrzynek.Aby uniknąć problemu z aliasami i zawsze uzyskać jeden adres IP gotowy do użycia:
źródło
działa bez zależności od innych systemów (i dla hostów określonych w / etc / hosts)
źródło
ping -q -c 1 -t 1 bahface.local | grep -m 1 PING | cut -d "(" -f2 | cut -d ")" -f1
getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>
pracuje dla deklaracji wewnątrz/etc/hosts
, zbyt ... i to go-to-narzędzie dla wszystkich rodzajów baz danych systemowych (passwd, grupy, aliasów, usług).Proste, ale przydatne:
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
Wszystkie polecenia rozpoznają adres IP, jeśli host nadal istnieje. Jeśli host wskazuje na CNAME, w tym przypadku również uzyska adres IP.
Pierwsze polecenie zwraca rozstrzygnięty adres IPv4
Drugie polecenie zwraca rozstrzygnięty adres IPv6
Trzecie polecenie zwróci adres właściciela, który może być adresem IPv4 lub IPv6.
źródło
host
że wymaga instalacjibindutils
Oto niewielka odmiana
ping
podejścia uwzględniającego „nieznanego hosta” (poprzez przepuszczanie przez stderr) i zastosowania wtr
celu uniknięcia użyciased
wyrażeń regularnych:W przypadku, gdy ważne jest przechwycenie wartości wyjściowej, następujące działania będą działać (choć mniej elegancko):
źródło
Aby wypełnić odpowiedź Chrisa Downa i odnieść się do komentarzy jfgagne na temat (prawdopodobnie powiązanych) aliasów, oto rozwiązanie, które:
/etc/hosts
pliku (w moim przypadku go nie chciałem); zapytać, rozwiązanie dbernta w Pythonie jest idealne)nie używa awk / sed
Zawsze zwraca pierwszy adres IP lub pusty tring, jeśli nie zostanie rozwiązany. z wersją dig:
źródło
źródło
Chciałbym dodać to jako komentarz do Andrew McGregor Re: ping. Jednak nie pozwoliłoby mi to, więc muszę dodać to jako kolejną odpowiedź. (Jeśli ktoś może zamienić go w komentarz, zachęcamy do.)
To kolejny wariant, wykorzystujący tylko ping i grep:
grep -E
dla rozszerzonego wyrażenia regularnego igrep -o
aby zwrócić tylko pasującą część. wyrażenie regularne szuka jednej lub wielu cyfr ([0-9]+
) i opcjonalnie kropki (\.?
) cztery razy ({4}
)źródło
Możesz użyć
host
:źródło
oto przepis na Bash, który ugotowałem na podstawie odpowiedzi innych ludzi - najpierw próbuje
/etc/hosts
, a potem wraca do nslookup:źródło
getent hosts
nie jest to tylko wyszukiwanie w / etc / hosts - to pełne rozpoznawanie DNS wywołania gethostbyaddr (3) i jest bardzo mało prawdopodobne, że zakończy się niepowodzeniem w przypadku, gdydig
się powiedzie. Zobacz stronę man dla getent .getent
pozostaje moim ulubionym, chociaż lubię teżdig +short
było rozwiązaniem, które znalazłem bez serwera DNS
źródło
Może nie jest to najbardziej zwięzłe, ale wydaje się być solidne i wydajne:
Spowoduje to wygenerowanie pojedynczego adresu IP IPv4, a także zwróci
1
w przypadku awarii, jednocześnie maskując wyjście stderr.Możesz użyć tego w następujący sposób:
Jeśli chcesz adres IPv6 zamiast, po prostu zastąpić
-4
z-6
.źródło
dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'
źródło
1 linia rozwiązuje listę nazw hostów
źródło
Cały czas robię to na komputerze Mac, którego nie ma
getent
.ping
wygląda na włamanie. Chciałbym również wziąć/etc/hosts
pod uwagę.Napisałem więc głupie opakowanie dla
dns.lookup
ciebie, który ma zainstalowany Node.js, aby zapewnić CLI:źródło
kopanie jest zbyt wolne, nslookup jest znacznie szybszy
źródło
Nie znam najprostszego sposobu na wykonanie skryptu bash, ale jeśli chcesz rozwiązać nazwę hosta i sprawdzić, czy host działa, użyj
ping
!Czy
ping
host raz i przekształci nazwę hosta w adres IP.źródło
Tak, jest już wiele odpowiedzi, ale brakuje rozwiązania wykorzystującego perl:
W skrypcie bash można go użyć w następujący sposób:
Zastosowane tutaj moduły są modułami podstawowymi, dlatego powinny być dostępne wszędzie bez instalowania z CPAN.
źródło
perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/null
jest znacznie czystszy. ale nikt z nas nie używa pörl, wszyscy inni oczywiście używają skryptu Pascal.Can't call method "addr" on an undefined value
nie jest najlepszym komunikatem o błędzie, ale może dać wskazówkę na temat problemu.źródło
print
zamiast tego należy użyćp
.to polecenie wyświetli adres IP (spowoduje zmianę adresu domeny na IP)
źródło
Oprócz powyższego rozwiązania możesz przetłumaczyć wiele nazw hostów na ip za pomocą poniższego skryptu, jedyną zależnością jest polecenie „ping” w rdzeniu Uniksa:
źródło