it-swarm-ko.tech

Bash 스크립트에서 호스트 이름을 IP 주소로 확인하려면 어떻게해야합니까?

Bash 스크립트에서 호스트 이름을 IP 주소로 확인하는 가장 간결한 방법은 무엇입니까? Arch Linux 를 사용하고 있습니다.

450
Eugene Yarmash

getent와 함께 제공되는 glibc를 사용할 수 있습니다 (따라서 Linux에서 거의 사용합니다). gethostbyaddr/gethostbyname2를 사용하여 해결되므로 /etc/hosts/NIS/etc :

getent hosts unix.stackexchange.com | awk '{ print $1 }'

또는 Heinzi가 아래에서 언급했듯이 Dig+short 인수 (DNS 서버에 직접 쿼리하고 /etc/hosts/NSS/etc) :

Dig +short unix.stackexchange.com

만약 Dig +short를 사용할 수 없으면 다음 중 하나가 작동합니다. 이러한 모든 쿼리는 DNS를 직접 쿼리하고 다른 해결 방법은 무시합니다.

Host unix.stackexchange.com | awk '/has address/ { print $4 }'
nslookup unix.stackexchange.com | awk '/^Address: / { print $2 }'
Dig unix.stackexchange.com | awk '/^;; ANSWER SECTION:$/ { getline ; print $5 }'

하나의 IP 만 인쇄하려면 exit 명령을 awk의 워크 플로우에 추가하십시오.

Dig +short unix.stackexchange.com | awk '{ print ; exit }'
getent hosts unix.stackexchange.com | awk '{ print $1 ; exit }'
Host unix.stackexchange.com | awk '/has address/ { print $4 ; exit }'
nslookup unix.stackexchange.com | awk '/^Address: / { print $2 ; exit }'
Dig unix.stackexchange.com | awk '/^;; ANSWER SECTION:$/ { getline ; print $5 ; exit }'
570
Chris Down

dnsutils 패키지에서 Host 사용 :

$ Host unix.stackexchange.com
unix.stackexchange.com has address 64.34.119.12

주석에 따라 ( 수정 된 패키지 이름입니다. 참고로 다른 배포판에는 다른 패키지에 Host가 있습니다 : Debian/Ubuntu bind9-Host, openSUSE bind-utils, Frugalware bind.)

146
manatwork

기계에 작업을 수행하는 것 같은 도구가 있습니다. 맨 페이지에는 mysql과 함께 제공되는 것 같습니다. 다음은 사용 방법입니다.

resolveip -s unix.stackexchange.com
64.34.119.12

호스트 이름을 확인할 수없는 경우이 도구의 반환 값은 0과 다릅니다.

resolveip -s unix.stackexchange.coma
resolveip: Unable to find hostid for 'unix.stackexchange.coma': Host not found
exit 2

UPDATE Fedora에서는 mysql-server와 함께 제공됩니다 :

yum provides "*/resolveip"
mysql-server-5.5.10-2.fc15.x86_64 : The MySQL server and related files
Dépôt         : Fedora
Correspondance depuis :
Nom de fichier      : /usr/bin/resolveip

나는 그것이 당신의 스크립트에 이상한 의존성을 만들 것이라고 생각합니다 ...

56
greg0ire

Dig를 사용하는 다음 명령을 사용하면 sed/awk/etc없이 결과를 직접 읽을 수 있습니다. 마법:

$ Dig +short unix.stackexchange.com
64.34.119.12

Digdnsutils 패키지에 포함되어 있습니다.


: Dig의 반환 값은 0 (이름을 확인할 수없는 경우에도). 따라서 반환 값을 확인하는 대신 출력이 비어 있는지 확인해야합니다.

hostname=unix.stackexchange.com

ip=`Dig +short $hostname`

if [ -n "$ip" ]; then
    echo IP: $ip
else
    echo Could not resolve hostname.
fi

주 2 : 호스트 이름에 여러 개의 IP 주소가있는 경우 (시도 debian.org, 예를 들어) 모두 반환됩니다. 이 "문제"는 지금까지이 질문에 언급 된 모든 도구에 영향을줍니다.

45
Heinzi
getent hosts unix.stackexchange.com | cut -d' ' -f1
44
sborsky

지금까지 제공된 솔루션은 대부분 더 간단한 경우에 작동합니다. 호스트 이름은 단일 IPv4 주소로 직접 확인됩니다. 이것은 호스트 이름을 해결해야하는 유일한 경우 일 수 있지만 그렇지 않은 경우 아래에서 처리해야 할 경우에 대한 설명입니다.

Chris Down과 Heinzi는 호스트 이름이 둘 이상의 IP 주소로 확인되는 경우에 대해 간단히 설명했습니다. 이 경우 (및 아래의 다른 경우) 호스트 이름이 단일 IP 주소로 직접 확인된다는 가정하에 기본 스크립팅이 중단 될 수 있습니다. 아래는 호스트 이름이 하나 이상의 IP 주소로 해석되는 예입니다.

$ Host www.l.google.com
www.l.google.com has address 209.85.148.147
www.l.google.com has address 209.85.148.103
www.l.google.com has address 209.85.148.99
www.l.google.com has address 209.85.148.106
www.l.google.com has address 209.85.148.105
www.l.google.com has address 209.85.148.104

하지만 www.l.google.com? 여기서 alias 사례를 소개해야합니다. 아래 예를 확인하십시오.

$ Host www.google.com
www.google.com is an alias for www.l.google.com.
www.l.google.com has address 74.125.39.103
www.l.google.com has address 74.125.39.147
www.l.google.com has address 74.125.39.105
www.l.google.com has address 74.125.39.99
www.l.google.com has address 74.125.39.106
www.l.google.com has address 74.125.39.104

그래서 www.google.com은 IP 주소로 직접 해석되지 않지만 여러 IP 주소로 자체 해석되는 별명으로 해석됩니다. 별명에 대한 자세한 정보는 here 를 확인하십시오. 물론, 아래와 같이 별명이 단일 IP 주소를 갖는 경우도 가능합니다.

$ Host g.www.ms.akadns.net
g.www.ms.akadns.net is an alias for lb1.www.ms.akadns.net.
lb1.www.ms.akadns.net has address 207.46.19.190

그러나 별칭을 연결할 수 있습니까? 대답은 '예'입니다.

$ Host www.Microsoft.com
www.Microsoft.com is an alias for toggle.www.ms.akadns.net.
toggle.www.ms.akadns.net is an alias for g.www.ms.akadns.net.
g.www.ms.akadns.net is an alias for lb1.www.ms.akadns.net.
lb1.www.ms.akadns.net has address 207.46.19.254

$ Host www.google.fr
www.google.fr is an alias for www.google.com.
www.google.com is an alias for www.l.google.com.
www.l.google.com has address 74.125.39.147
www.l.google.com has address 74.125.39.103
www.l.google.com has address 74.125.39.99
www.l.google.com has address 74.125.39.106
www.l.google.com has address 74.125.39.104
www.l.google.com has address 74.125.39.105

호스트 이름이 IP 주소로 확인되지 않는 별칭으로 확인되는 예를 찾지 못했지만 문제가 발생할 수 있다고 생각합니다.

여러 개의 IP 주소 및 별칭보다 더 특별한 경우가 있습니까? IPv6는 어떻습니까? 시도해 볼 수 있습니다 :

$ Host ipv6.google.com
ipv6.google.com is an alias for ipv6.l.google.com.
ipv6.l.google.com has IPv6 address 2a00:1450:8007::68

호스트 이름 ipv6.google.com는 IPv6 전용 호스트 이름입니다. 이중 스택 호스트 이름은 어떻습니까?

$ Host www.facebook.com
www.facebook.com has address 66.220.153.15
www.facebook.com has IPv6 address 2620:0:1c08:4000:face:b00c::

다시 IPv6에 대해, 호스트가 IPv4 전용 인 경우에도 IPv6 주소를 확인할 수 있습니다 (IPv4 전용 WinXP 및 ipv6.google.com에서 테스트 한 경우 Linux에서 시도 할 수 있음). 이 경우 해결에 성공하지만 알 수없는 호스트 오류 메시지와 함께 핑이 실패합니다. 스크립팅이 실패하는 경우 일 수 있습니다.

그 말이 도움이 되었기를 바랍니다.

30
jfg956

별명에 대한 문제점을 피하고 항상 사용할 단일 IP 주소를 확보하려면 다음을 수행하십시오.

python -c 'import socket; print socket.gethostbyname("www.example.com")'
22
dbernt

간단하지만 유용합니다.

  1. getent ahostsv4 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
  2. getent ahostsv6 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
  3. getent hosts google.de | head -n 1 | cut -d ' ' -f 1

호스트가 여전히 존재하면 모든 명령은 IP 주소를 확인합니다. 호스트가 CNAME을 가리키면이 경우 IP도 얻게됩니다.

첫 번째 명령은 확인 된 IPv4 주소를 반환합니다

두 번째 명령은 확인 된 IPv6 주소를 반환합니다

세 번째 명령은 소유자가 선호하는 주소 인 IPv4 또는 IPv6 주소를 반환합니다.

19
Tom Freudenberg
ping -q -c 1 -t 1 your_Host_here | grep PING | sed -e "s/).*//" | sed -e "s/.*(//"

다른 시스템 및/etc/hosts에 지정된 호스트에 대한 종속성없이 작동

19
Andrew McGregor

다음은 "알 수없는 호스트"를 고려하고 (stderr를 통한 파이프 연결) ping 정규식 사용을 피하기 위해 tr를 사용하는 sed 접근 방식의 약간의 변형입니다.

ping -c1 -t1 -W0 www.example.com 2>&1 | tr -d '():' | awk '/^PING/{print $3}'

종료 값을 캡처하는 것이 중요한 경우에는 다음과 같이 작동합니다 (아주 우아하지는 않음).

ping -c1 -t1 -W0 www.example.com &>/dev/null && ping -c1 -t1 -W0 www.example.com 2>&1 | tr -d '():' | awk '/^PING/{print $3}'
9
Stefan Farestam

Chris Down의 답변을 완성하고 (연쇄 적으로 연결된) 별칭에 대한 jfgagne 의견을 해결하려면 다음과 같은 해결책이 있습니다.

  • 여러 개의 IP를 고려
  • 하나 이상의 별칭 (CNAME)을 고려합니다.
  • /etc/hosts 파일을 쿼리하지 않습니다 (제 경우에는 원하지 않았습니다). 그것을 쿼리하기 위해 dbernt의 python 솔루션은 완벽합니다)
  • awk/sed를 사용하지 않습니다

    Dig +short www.alias.com  | grep -v "\.$" | head -n 1
    

항상 첫 번째 IP 주소를 반환하거나 해결되지 않은 경우 비어있는 트링을 반환합니다. Dig 버전으로 :

    $ Dig -v
    Dig 9.8.1-P1
8
Franck
 php -r "echo gethostbyname('unix.stackexchange.com');"
6
Mohammed Zourob

Andrew McGregor Re : ping의 의견으로 이것을 추가하고 싶었습니다. 그러나 그것은 나를 허락하지 않을 것이므로 이것을 다른 대답으로 추가해야합니다. (누군가가 댓글로 의견을 옮길 수 있다면 자유롭게 느끼십시오.)

이것은 ping과 grep 만 사용하는 또 다른 변형입니다.

ping -q -c1 -t1 your_Host_here | grep -Eo "([0-9]+\.?){4}"

grep -E 정규 표현식 확장 및 grep -o 일치하는 부분 만 반환합니다. 정규 표현식 자체는 하나 이상의 숫자를 찾습니다 ([0-9]+) 및 선택적으로 점 (\.?) 네번 ({4})

6
Dweia
nmap -sP 192.168.178.0/24|grep YOUR_HOSTNAME|sed -n 's/.*[(]\([0-9\.]*\)[)].*/\1/p'

dNS 서버없이 찾은 솔루션이었습니다

5
Philippe Gachoud

다음은 다른 사람들의 답변을 사용하여 요리 한 배쉬 레시피입니다.-먼저 시도 /etc/hosts, nslookup으로 넘어갑니다.

resolveip(){
    local Host="$1"
    if [ -z "$Host" ]
    then
        return 1
    else
        local ip=$( getent hosts "$Host" | awk '{print $1}' )
        if [ -z "$ip" ] 
        then
            ip=$( Dig +short "$Host" )
            if [ -z "$ip" ]
            then
                echo "unable to resolve '$Host'" >&2 
                return 1
            else
                echo "$ip"
                return 0
            fi
        else
            echo "$ip"
            return 0
        fi
    fi
}
5
RubyTuesdayDONO

Host를 사용할 수 있습니다 :

hostname=example.org

# strips the IP
IP=$( Host ${hostname} | sed -e "s/.*\ //" )

# checks for errors
if [ $? -ne 0 ] ; then
   echo "Error: cannot resolve ${hostname}" 1>&2
   exit 1;
fi
5
Matteo

아마도 가장 간결하지는 않지만 강력하고 효율적인 것 같습니다.

# $(get_Host_dns_short "google.com")
#
# Outputs the IPv4 IP Address of a hostname, resolved by DNS. Returns 0 if DNS
# responded successfully; 1 otherwise. Will mask error output.
function get_Host_dns_short()
{
    (
        set -o pipefail

        Host -4 -W1 -t A "$1" 2>/dev/null | awk '/has address/ { print $NF; exit }'
    ) && return 0 || return 1
}

Stderr 출력을 마스킹하는 동안 실패시 단일 IPv4 IP를 출력하고 1를 반환합니다.

다음과 같이 사용할 수 있습니다.

GOOGLE_IP="$(get_Host_dns_short "google.com")"
if [[ $? -eq 0 ]]; then
    echo "Google's IP is ${GOOGLE_IP}."
else
    echo "Failed to resolve Google's IP."
fi

Google의 IP는 216.58.192.46입니다.

IPv6 주소를 원한다면 -4-6로 바꾸십시오.

4
Will

발굴이 너무 느리고 nslookup이 훨씬 빠릅니다.

nslookup google.com | grep -Po 'Address:\s*[0-9.]+' | tail -1 | sed -e 's/Address:\s*//g'
4
Andrey Izman

Dig +noall +answer +nocomments example.com | awk '{printf "%-36s\t%s\n", $1, $5 }'

4
D P Baker

한 줄은 호스트 이름 목록을 확인합니다.

for LINE in `cat ~/Desktop/mylist`; do a=$(nslookup $LINE | awk '/^Address: / { print $1 }');  echo $a >> ~/Desktop/ip; done
3
Andy Wong

Bash 스크립트의 가장 쉬운 방법은 모르지만 호스트 이름을 확인하고 호스트가 작동하는지 확인하려면 ping!

ping -a hostname -c 1

호스트를 한 번 ping하고 호스트 이름을 IP 주소로 확인합니다.

$ ping -a www.google.com -c 1
PING www.google.com (216.58.211.132) 56(84) bytes of data.
64 bytes from arn09s10-in-f4.1e100.net (216.58.211.132): icmp_seq=1 ttl=54 time=1.51 ms
3
user257655

getent가없는 Mac에서 항상이 작업을 수행하고 있습니다. ping는 해킹처럼 보입니다. /etc/hosts도 고려하고 싶습니다.

CLI를 제공하기 위해 Node.js를 설치 한 사용자를 위해 dns.lookup에 대한 바보 래퍼를 작성했습니다.

$ npm install -g lookup-hostname
$ lookup google.com
62.243.192.89
3
Thomas Jensen
#!/bin/bash

systemd-resolve   RT.com -t A  | awk '{ print $4 ; exit }'
systemd-resolve unix.stackexchange.com -t A --legend=no | awk '{ print $4 ; exit }'

resolveip -s      RT.com
Dig       +short  RT.com
Host              RT.com | awk '/has address/ { print $4 }'
nslookup          RT.com | awk '/^Address: /  { print $2 }'
ping -q -c 1 -t 1 RT.com | grep PING | sed -e "s/).*//" | sed -e "s/.*(//"

Ruby     -rresolv -e      ' print    Resolv.getaddress "RT.com" '
python2  -c 'import socket; print socket.gethostbyname("RT.com")'
Perl     -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' RT.com  2>/dev/null
php      -r "echo gethostbyname( 'RT.com' );"

echo        "   all do work for me - take your pick!  "
2
dotbit

예, 이미 많은 답변이 있지만 Perl을 사용하는 솔루션이 없습니다.

Perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com

Bash 스크립트에서는 다음과 같이 사용할 수 있습니다.

#!/bin/bash
ipaddr=$(Perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com)
echo $ipaddr

여기에 사용 된 모듈은 핵심 모듈이므로 CPAN과 함께 설치하지 않고도 어디서나 사용할 수 있습니다.

2
Slaven Rezic