Automating DNS Lookups with dig and host in Bash
AI generated
$_
#!/
Bash · Networking · DNS · Monitoring
Automating DNS Lookups with dig and host
From a single query to a monitoring script

Anyone who only checks DNS records one at a time by hand misses propagation problems and silent changes. Automating DNS lookups with dig and host processes domain lists in seconds, compares resolvers, and catches configuration mistakes before customers report them.

17 min read dig +short · host · getent Bash 4.x/5.x · Linux · Cron

1. Why DNS lookups get automated in Bash

DNS problems are among the most common yet hardest to spot causes of outages: a misconfigured A record, a forgotten MX entry, or a resolver still caching stale values leads to errors that never show up in application code. Anyone automating DNS lookups with dig and host moves this check out of a manual "let me just look" and into a repeatable, documented script.

Especially during domain migrations, hosting provider switches, or the rollout of new subdomains, it is crucial to know the status of many domains at once, not just a single one. A Bash script that automates DNS lookups checks hundreds of domains against multiple resolvers in seconds and delivers a structured overview instead of individual terminal outputs.

Automation also pays off during ongoing operations: DNS entries change less often than application code, but when they do change, the impact is often significant, for example during a CDN switch or a new mail server configuration. A script that automates DNS lookups with dig and host and runs regularly reliably detects such changes long before a user reports a failed email delivery.

2. dig, host and nslookup: the tools at a glance

Three classic tools are available for automating DNS lookups with dig and host in Bash. dig (Domain Information Groper) from the bind-utils or dnsutils package delivers the most detailed and best scriptable output, including explicit options to reduce it to exactly the information needed. host is more concise in its default output and works well for quick, readable one-liners.

nslookup is historically older, considered less consistent across platforms, and is generally no longer recommended for new scripts, though it still shows up in many older tutorials. For Bash automation, dig is the more robust choice because it provides explicit flags for machine-readable output that host and nslookup lack in this form.


#!/usr/bin/env bash
# dns-tools-check.sh — verify dig, host and nslookup availability
set -euo pipefail

for tool in dig host nslookup getent; do
  if command -v "$tool" &>/dev/null; then
    echo "[OK] $tool: $(command -v "$tool")"
  else
    echo "[MISSING] $tool not installed"
  fi
done

echo "---"
echo "dig version: $(dig -v 2>&1 | head -n 1)"

3. Parseable output with dig +short and +noall +answer

The key to automating DNS lookups with dig and host lies in the right output formatting. dig +short example.com returns only the IP address, without header, question section, or statistics lines, perfect for reading directly into a Bash variable. For more context, but still machine readable, dig +noall +answer example.com returns only the answer section with TTL and record type, without the rest of the noise.

These two modes cover most automation cases: +short for simple existence and value checks, +noall +answer when TTL values or multiple records per domain matter. Anyone who automates DNS lookups with dig and host and wants to process the output further with awk or jq should consistently stick to one of the two formats rather than mixing both in one script.


#!/usr/bin/env bash
# dig-parse-formats.sh — compare short vs. detailed dig output
set -euo pipefail

DOMAIN="${1:-mironsoft.de}"

echo "=== dig +short (only the value) ==="
dig +short "$DOMAIN" A

echo "=== dig +noall +answer (value + TTL + record type) ==="
dig +noall +answer "$DOMAIN" A

echo "=== Extract just the IP with awk from +noall +answer ==="
dig +noall +answer "$DOMAIN" A | awk '{print $NF}'

4. Batch-querying domain lists from files

As soon as more than a handful of domains need checking, a domain list in a text file, one domain per line, combined with a Bash loop pays off. Reading the file robustly matters here too: while IFS= read -r domain; do ... done < domains.txt avoids problems with leading or trailing whitespace and respects comment lines once you filter them out beforehand with grep -v '^#'.

For automating DNS lookups with dig and host at scale, dig also offers the -f option, which processes an entire file of queries in a single dig invocation, which is significantly faster than hundreds of individual process calls in a Bash loop, because only a single connection to the resolver is established.


#!/usr/bin/env bash
# batch-dns-check.sh — check a list of domains for their A record
set -euo pipefail

DOMAIN_FILE="${1:?Usage: batch-dns-check.sh <domain-list-file>}"
declare -A results=()

while IFS= read -r domain; do
  [[ -z "$domain" || "$domain" == \#* ]] && continue
  ip=$(dig +short "$domain" A | head -n 1)
  results["$domain"]="${ip:-NO_RECORD}"
done < "$DOMAIN_FILE"

echo "=== Batch DNS results ==="
for domain in "${!results[@]}"; do
  printf '%-30s -> %s\n' "$domain" "${results[$domain]}"
done

# Faster alternative: dig -f processes the whole file in one dig invocation
echo "=== Same result via 'dig -f' (single resolver round trip) ==="
dig +short -f "$DOMAIN_FILE"

5. Querying specific record types: A, AAAA, MX, TXT, NS

Besides the A record for IPv4 addresses, AAAA (IPv6), MX (mail server), TXT (SPF, DKIM, domain verification), and NS (name server) are among the most frequently checked types. Anyone automating DNS lookups with dig and host to, for example, validate an email configuration, specifically queries dig +short example.com MX and checks whether the expected mail server is entered with the correct priority.

For TXT records, which often contain multi-line or quoted values (such as SPF entries like "v=spf1 include:_spf.google.com ~all"), a script must strip the surrounding quotes before further processing the value. dig +short example.com TXT | tr -d '"' is the pragmatic solution here.


#!/usr/bin/env bash
# check-record-types.sh — query multiple DNS record types for one domain
set -euo pipefail

DOMAIN="${1:?Usage: check-record-types.sh <domain>}"

declare -a RECORD_TYPES=(A AAAA MX TXT NS CNAME)

for record_type in "${RECORD_TYPES[@]}"; do
  echo "--- $record_type ---"
  result=$(dig +short "$DOMAIN" "$record_type")
  if [[ -z "$result" ]]; then
    echo "  (no record)"
  else
    echo "$result" | sed 's/^/  /'
  fi
done

6. Comparing DNS propagation across multiple resolvers

After a DNS change, the immediate question is whether and how quickly it has propagated. Because different resolvers have different TTL caches, a query against the local resolver often returns a different result than a query against a public resolver like Google (8.8.8.8) or Cloudflare (1.1.1.1). Anyone automating DNS lookups with dig and host to check propagation therefore deliberately queries several resolvers with the @resolver-ip option and compares the results.

Such a comparison script immediately shows whether a change has arrived everywhere or whether a particular resolver still returns an outdated, cached value. That is especially valuable for time-critical migrations, where you need to know whether the old or new server is still receiving traffic.


#!/usr/bin/env bash
# propagation-check.sh — compare A record across multiple public resolvers
set -euo pipefail

DOMAIN="${1:?Usage: propagation-check.sh <domain>}"

declare -A RESOLVERS=(
  [Google]="8.8.8.8"
  [Cloudflare]="1.1.1.1"
  [Quad9]="9.9.9.9"
  [OpenDNS]="208.67.222.222"
)

echo "=== A record for $DOMAIN across resolvers ==="
for name in "${!RESOLVERS[@]}"; do
  ip="${RESOLVERS[$name]}"
  result=$(dig +short "@$ip" "$DOMAIN" A | head -n 1)
  printf '%-12s (%s) -> %s\n' "$name" "$ip" "${result:-NO_ANSWER}"
done

7. A monitoring script: detecting changes and alerting

A one-time check is not enough for ongoing monitoring. A cron job that automates DNS lookups with dig and host and compares the current value to the last known value detects unauthorized or unexpected changes immediately. The values are stored in a simple file or SQLite database and reconciled on every run.

On a mismatch, the script sends a notification, for example via a Slack webhook or email, and logs the timestamp, old value, and new value. For critical domains whose MX or A records should never change without notice, such monitoring is a simple but effective safeguard against DNS hijacking or accidental misconfiguration by third parties.

Tool Output Format Scriptability Recommendation
dig +short Value only, no extras Very good Default choice for Bash scripts
dig +noall +answer Value + TTL + type Good When TTL matters
host Compact text line Harder to parse For interactive one-liners
getent hosts Local resolver view only Medium Check system resolution incl. /etc/hosts
nslookup Inconsistent across systems Poor Avoid for new scripts

Mironsoft

Shell automation, DNS monitoring and deployment infrastructure

Keeping DNS configuration in view, for every domain?

We automate DNS checks for domain migrations, monitor critical records continuously, and alert your team on unexpected changes before customers notice anything.

Migration Checks

Batch queries and resolver comparison for safe domain moves

DNS Monitoring

Regular checks of critical records with change alerts

Error Analysis

Diagnosing SERVFAIL, NXDOMAIN, and propagation delays

8. Diagnosing SERVFAIL, NXDOMAIN and timeouts

Anyone automating DNS lookups with dig and host has to be able to distinguish different error responses to react sensibly in the script. NXDOMAIN means the domain simply does not exist, often a typo or a not-yet-registered domain. SERVFAIL, on the other hand, points to a configuration problem at the authoritative name server, such as a broken DNSSEC signature or an unreachable name server.

A third case, timeouts, usually arises from network problems between the client and the resolver, not from the domain itself. In a Bash script, you check the status via dig ... | grep -q "status: NOERROR" or read the command's return value directly, where dig returns a non-zero exit code on network errors, while an NXDOMAIN still returns exit code 0, because the query itself was technically successful, just without a result.

9. dig vs. host vs. getent compared

The table in section seven shows the key differences, but the context matters too: getent hosts uses the system's local name resolution including /etc/hosts and the configured nsswitch.conf order, while dig and host query the DNS resolver directly by default and ignore local overrides. For debugging applications that go through system resolution (such as PHP with gethostbyname), getent is therefore often more informative than a plain dig call.

For pure DNS diagnostics and automation, dig remains the first choice, because it offers the most fine-grained options for output format, resolver selection, and record type. host still works well for quick interactive checks in the terminal, where readability matters more than scriptability.

10. Summary

Automating DNS lookups with dig and host means moving DNS checks from manual single queries into a repeatable, scriptable tool. dig +short delivers the cleanest output for simple value checks, dig +noall +answer adds TTL and record type, and batch processing with a domain list or dig -f scales to hundreds of domains without manual effort.

For migrations, comparing several public resolvers is decisive for verifying propagation. For ongoing operations, a monitoring script that automates DNS lookups with dig and host and logs changes delivers a simple but effective safeguard against unnoticed DNS misconfiguration and hijacking attempts.

Automating DNS Lookups with dig and host — The Essentials at a Glance

Output Format

dig +short for values, dig +noall +answer for values including TTL and type.

Batch Processing

A domain list plus a while loop, or dig -f for a single resolver round trip.

Propagation

Query several resolvers with @resolver-ip and compare the results.

Error Diagnosis

Cleanly distinguish NXDOMAIN, SERVFAIL, and timeout, each with different causes and reactions.

11. FAQ: Automating DNS Lookups with dig and host

1Why dig instead of nslookup?
dig offers explicit flags for machine-readable output, nslookup formats inconsistently across platforms.
2Hundreds of domains without hundreds of processes?
dig -f domainlist.txt processes all queries with a single resolver round trip.
3Extract just the IP address?
dig +short domain.tld A suppresses all extras and returns just the value.
4Check propagation across resolvers?
dig @resolver-ip against several public resolvers, then compare results.
5SERVFAIL vs. NXDOMAIN?
NXDOMAIN means the domain does not exist. SERVFAIL points to a name server configuration problem.
6TXT records with quotes?
dig +short domain.tld TXT | tr -d '"' removes the surrounding quotes.
7What is getent hosts good for?
Uses local system resolution including /etc/hosts, relevant for debugging system-level applications.
8Simple DNS monitoring with cron?
Query the value via dig +short, compare to stored value, notify on mismatch.
9Error vs. network timeout?
Network problems return a non-zero exit code, NXDOMAIN still returns exit code 0.
10Evaluate MX records with priority?
dig +short domain.tld MX returns priority and mail server, splittable into two fields with awk.