Bashスクリプトでホスト名をIPアドレスに解決するにはどうすればよいですか?

Bashスクリプトでホスト名をIPアドレスに解決する最も簡潔な方法は何ですか?私は Arch Linux

コメント

  • getent <ahosts|ahostsv4|ahostsv6|hosts> <hostname>が答えるのは残念です底の近くのどこかにあります。 ‘は最も単純で、追加のパッケージを必要とせず、Bashスクリプトからの解析も簡単です。
  • @ 0xC0000022L:新しい残念なことに、somehostを実行すると、その回答はgetent hosts somehostを示唆します。 / div> はIPv6アドレスを生成します。これは、他のほとんどのツール(pingssh少なくとも)名前を解決し、いくつかのことを壊します。 hostsの代わりにahostsを使用します。
  • @j_random_hacker:特にIPv4を要求しないようにします(ahostsv4または IPv6(ahostsv6)アドレス?個人的には、IPv6を返す不特定のリクエストに問題はありません。コードを準備する必要があります。 IPv6は20年以上前から存在しています。
  • @ 0xC0000022L:誰も”私を”それを行うが、答えは具体的にhostsを示唆しており、これまでに4人がivによって引き起こされた痛みを表すvinc17 ‘のコメントに賛成しています。 id = “249a1af967”>

突然IPv6 “。 IPv6の準備が常に問題になるとは限りません。多くのプログラムでは、2つの名前/アドレスが同じホストを参照しているかどうかを判断する方法が必要です。単純な文字列照合を使用するか、” true “の答えを見つけるためにネットワークについて多くのことを知っている必要があります。後者は地雷原であるため、私が制御できないほど多くのサードパーティのプログラムやシステムが前者を使用しています。

回答

glibcに付属しているgetentを使用できます(Linuxでもほぼ確実に使用できます) 。これはgethostbyaddr / gethostbyname2を使用して解決されるため、/etc/hosts / NIS / etc:

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

または、 Heinziが以下で述べているように、dig+short引数とともに使用できます(DNSサーバーに直接クエリを実行し、 / 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 }" 

1つのIPのみを出力する場合は、コマンドで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 }" 

コメント

  • デフォルトでは、digの使用はipv4でのみ機能し、ホストはipv4とipv6の両方の回答を提供します。これは予期しない場合があります。host www.google.comdig +short www.google.comhost ipv6.google.comdig +short ipv6.google.comhost www.facebook.comdig +short www.facebook.com
  • DIGは機能しません。CNAMEの場合、IPは返されません。
  • 場合によっては、hostはタイムアウトして何も返さない場合があります。一部のドメインでは、dig +shortが最初の行にドメインエイリアスを返す場合があります。したがって、出力がIPv4であることを確認します。アドレス、dig +short example.com | grep -Eo '[0-9\.]{7,15}' | head -1を使用します。
  • getent hosts <host>の使用は、インスタンスの場合と同様に正しくありませんCEは、IPv6が機能しないときにIPv6アドレスを提供する場合があります’。正しい解決策は、必要に応じてgetent ahosts <host>を使用してIPv6とIPv4の両方を試すことです。
  • 注目に値する:host、dig、nslookupはリストされているサーバーと直接通信しているようですresolv.conf内で、”取得ホスト”が有効になっている場合は、ローカルホストファイルとライブラリレベルのキャッシュ(nscdなど)の両方を尊重します。

回答

ividからhostを使用= “42fabf6d41”>

dnsutils パッケージ:

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

修正済み パッケージ名。注として、他のディストリビューションでは、さまざまなパッケージにhostがあります:Debian / Ubuntu bind9-host 、openSUSE bind-utils 、Frugalware bind 。)

コメント

  • DNSにないもの(例:/ etc / hosts)を解決する必要がある場合は、以下のresolveipエントリを参照してください。
  • 次の点に注意してくださいhostが複数行の出力を返す場合があります(リダイレクトの場合)。’ host unix.stackexchange.com | tail -n1 IPアドレスを含む行が必要な場合。
  • ” host “には、出力形式が異なる複数のバージョンがあります。例えば。ほとんどのシステムにはBIND9バージョンがあるようですが、私のUbuntu 10.04LTSサーバーにはまったく異なるバージョンがあります。
  • ‘がない場合hostまたはdigがインストールされている場合は、代わりにpingを使用できます。これは常に利用可能です:ping unix.stackexchange.com -c 1 -q 2>&1 | grep -Po "(\d{1,3}\.){3}\d{1,3}"これは必要ありません追加のパッケージはほとんどのUnix / Linuxマッチインにインストールされます。
  • この回答は深刻な反対意見に値します。 hostはDNSツール(nslookupに類似)であるため、DNSでホストのみを検索し、たとえばでは検索しません。 /etc/hosts。したがって、OP ‘の質問に対する回答はないです。

回答

自分のマシンにその仕事をしているように見えるツールがあります。マニュアルページには、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 

スクリプトに奇妙な依存関係が作成されると思います…

コメント

  • これは、OS ‘のビルドインリゾルバーを使用するここでの唯一のソリューションのようです。 / etc / hostsとDNS。
  • getentは、他の回答で詳しく説明されているように、/ etc / hostsも調べ、glibcが付属しているためです。 Linuxシステムへの依存関係はありません。
  • 別のパッケージへの依存関係を作成するため、resolveipは使用しません。 getentはデフォルトでインストールされます。 host、nslookup、およびdigはすべてオプションのパッケージに含まれています。スクリプトでは必ずgetentを使用してください。
  • この回答は気に入っていますが、’はipv6を返しません

回答

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を試してください)、それらはすべて次のようになります。この「問題」は、これまでにこの質問で言及されたすべてのツールに影響します。

コメント

  • ドメインにCNAMEエントリがある場合は注意してください。そのドメインは、IPアドレスの代わりに最初の行に出力される場合があります。

回答

getent hosts unix.stackexchange.com | cut -d" " -f1 

コメント

  • ahostsahostsv4ahostsv6getent
  • cutはgetent ‘。これは\tを使用して列を区切ります。これはSolarisの場合です。
  • @ceving:ソラについて-dなしでcutを実行する必要がある場合があります(デフォルトでは区切り文字として\t)。 Linuxでは、’スペースがあるため、上の行が機能します。

回答

これまでに示した解決策は、ほとんどの場合、より単純なケースで機能します。ホスト名は、単一の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とは?ここで、エイリアスのケースを導入する必要があります。以下の例を確認してみましょう。

$ 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アドレスに解決されるエイリアス。エイリアスの詳細については、こちらを確認してください。もちろん、エイリアスに単一の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で試すことができます)。この場合、解決は成功しますが、pingは不明なホストエラーメッセージで失敗します。これは、スクリプトが失敗する場合である可能性があります。

これらのコメントがお役に立てば幸いです。

コメント

  • すばらしい。受け入れられた回答を補足し、スクリプトで処理する可能性のあるすべてのエッジケースを示します。私のバージョンhostには、ボックスのアドレス”がある”も記載されていません。

回答

エイリアスの問題を回避し、常に単一のIPアドレスを使用できるようにするには:

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

コメント

回答

ping -q -c 1 -t 1 your_host_here | grep PING | sed -e "s/).*//" | sed -e "s/.*(//" 

他のシステムに依存せずに(および/ etc / hostsで指定されたホストに対して)機能します

コメント

  • hostsファイルの値が必要なので、pingを使用する必要がありますが、sedパターンは正しく解析されますが、これはpingで機能しました- q -c 1 -t 1 your_host_here | grep PING | sed -e ” s / ^ [^(] * [(] // ” | sed -e ” s / [)]。* $ // ”
  • myhostname.localのようなホームネットワーク上の何かを解決するには、これは次のように機能します。私はこれがベストアンサーです。
  • これも提案できます: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、group、alias、services)用。

回答

シンプルだが便利:

  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アドレスを返します。

2番目のコマンドはresを返します。解決されたIPv6アドレス。

3番目のコマンドは、所有者の優先アドレスを返します。これは、IPv4またはIPv6アドレスのいずれかです。

コメント

  • これまでで最も単純なもの。そして、そのデフォルトで利用可能です。 bindutils

回答 h2のインストールが必要なhostとは異なります>

これは、pingアプローチのわずかなバリエーションであり、「不明なホスト」を考慮し(stderrを介してパイプすることにより)、

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}" 

コメント

  • 追加のツールがなくても機能するため、このソリューションが大好きです。

回答

Chris Downの回答を完成させ、(おそらくチェーンされた)エイリアスに関するjfgagneのコメントに対処するために、次のソリューションがあります:

  • 複数のIPを考慮に入れる
  • 1つ以上のエイリアス(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 

コメント

  • ありがとうございます。他の回答では、” dig + short ” 常にが返されると想定しています。単一のIPアドレス。’はCNAMEを考慮していませんでした。

回答

 php -r "echo gethostbyname("unix.stackexchange.com");" 

コメント

  • これは機能しますが、端末にphpがインストールされている必要があります
  • ” host “、” dig “などは利用できません

回答

Andrew McGregor Re:pingへのコメントとしてこれを追加したいと思います。ただし、許可されないため、これを別の回答として追加する必要があります(誰かがコメントに移動できる場合は、遠慮なくしてください)。

これは別のバリエーションで、pingとgrepのみを使用します。 :

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

grep -Eは拡張正規表現、grep -oは一致する部分のみを返します。正規表現自体は、1桁または複数桁([0-9]+)と、オプションでドット(\.?)を4回検索します( {4}

回答

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 

回答

here “saBashレシピ私は他の人々の答えを使って料理を作りました—最初に/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 }  

コメント

  • 明確にするために、getent hostsはありません’ / etc / hostsでのルックアップだけではありません-‘ gethostbyaddr(3)であり、digdigは成功します。 取得者のマニュアルページを参照してください。
  • @Stuartは正しいです— ‘学習しましたそれを書いて、強力なコマンドを単純化しすぎて以来、かなりのことです。 getentは私のお気に入りですが、dig +short

回答

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

DNSサーバーなしで見つけた解決策でした

回答

おそらく最も簡潔ではありませんが、堅牢で効率的であるようです:

# $(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 } 

これにより単一のIPv4が出力されますIP、および失敗した場合は1を返し、stderr出力をマスクします。

次のように使用できます:

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に置き換えてください。

回答

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

コメント

  • その答えが既存のものよりもどのように改善されるかについてのいくつかのコンテキスト素晴らしいこと。また、コマンドを4つのスペースでインデントしてください(マークダウン構文を参照)。

回答

digも遅い、nslookupははるかに高速です

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

回答

1行でリストを解決しますホスト名の

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

回答

これは常に自分のgetentがないMac。 pingはハックのようです。 /etc/hostsも考慮に入れたいと思います。

そこで、dns.lookupの愚かなラッパーを作成しました。 CLIを提供するためにNode.jsをインストールしている場合:

$ npm install -g lookup-hostname $ lookup google.com 62.243.192.89 

コメント

  • 60%の確率解決に近づく前に破損する可能性があります。
  • @dotbit詳しく説明していただけますか? ‘ ‘ 17以降、今週は毎週使用していますが、問題は発生していません。
  • @Jensenですが、’いつものように、これまでで唯一のものです。私たちの残りの部分は通常、ある種のFAILに遭遇し、常にそうです。
  • “いつものように” それはどういう意味ですか? “残りのメンバー” 誰が’ ? “失敗に遭遇” どのような特定の問題が発生していますか? ‘興味があります。

回答

私はしません ” bashスクリプトの最も簡単な方法を知っていますが、ホスト名を解決してホストが起動しているかどうかを確認する場合は、pingを使用してください!

ping -a hostname -c 1 

pingホストを1回実行し、ホスト名を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 

コメント

  • pingを使用するのは良いことです。誰もがそれを持っているからですが、そうする必要があります。スクリプトで使用する場合は、出力からIPパーツをフィルタリングします。

回答

はい、すでに多くの答えがありますが、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を使用せずにどこでも利用できるはずです。

コメント

  • perl -MSocket -MNet::hostent -E 'say inet_ntoa((gethost shift)->addr)' unix.stackexchange.com 2>/dev/nullははるかにクリーンです。しかし、私たち2人だけがp ö rlを使用しています。もちろん、他の全員がPascalスクリプトを使用しています。
  • 実際、エラーメッセージが表示されることを好みます。うまくいかない。 Can't call method "addr" on an undefined valueは’正確に最良のエラーメッセージではありませんが、問題についてのヒントを与える可能性があります。

回答

#!/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! " 

コメント

  • ルビーバージョンはIPアドレスの周りに引用符を出力します—おそらくpの代わりにprintを使用する必要があります。
  • thx、@ Slaven Rezic、そして気軽に賛成してください。繰り返しになりますが、ここの下部では、スクリプトが実際に表示されている可能性があります… 😉

回答

host -t a cisco.com 

このコマンドはIPアドレスを表示します(ドメインをIPに再参照します)

回答

上記のソリューションに加えて、以下のスクリプトを使用して複数のホスト名をipに変換できます。依存関係はコアUnixの「ping」コマンドのみです。

getip(){ ping -c 1 -t 1 $1 | head -1 | cut -d " " -f 3 | tr -d "()" 2>&1 | tee >> /tmp/result.log & } getip "hostname.number1.net" getip "hostname.number2.net" getip "hostname.number3.net" getip "hostname.number4.net" getip "hostname.number5.net" getip "hostname.number6.net" getip "hostname.number7.net" getip "hostname.number8.net" 
$ cat /tmp/result.log ABC.DEF.GHI.XY1 ABC.DEF.GHI.XY2 ABC.DEF.GHI.XY3 ABC.DEF.GHI.XY4 ABC.DEF.GHI.XY5 ABC.DEF.GHI.XY6 ABC.DEF.GHI.XY7 ABC.DEF.GHI.XY8 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です