Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to write a bash script for OS X that will change will add a nameserver for the current connection. I've got the command to change the DNS servers but I need to preserve the current namesever.

What I thought is that I could get the current nameserver out of the resolv.conf file and then use this somehow in the command.

I've currently got this to change the nameserver to 8.8.8.8:

networksetup -setdnsservers AirPort 8.8.8.8

What I need to do is detect the current nameserver from /etc/resolv.conf and then use the value as a param in the above command. For example say my current resolv.conf looks like this:

nameserver 9.9.9.9

I want the above to command to do this:

networksetup -setdnsservers AirPort 9.9.9.9, 8.8.8.8

Is there a way to use regular expression to extract the IP from resolv.conf and then somehow use this as an argument in the networksetup command?

share|improve this question
add comment

3 Answers 3

up vote 2 down vote accepted

Minimally tested; for best results, in each [ ], add a tab inside the brackets:

networksetup -setdnsservers AirPort $(sed -ne 's/^[ ]*nameserver[ ]\+\([.:0-9A-Fa-f]\+\)/\1/p' /etc/resolv.conf)

The sed expression extracts addresses from lines that start with the word nameserver followed by an IPv4 or IPv6 address. The $() construct interpolates the output of sed onto the command line of networksetup.

If there's a chance that there won't be any nameserver line in /etc/resolv.conf, here's a relatively simple way:

nameservers=$(sed -ne 's/^[ ]*nameserver[ ]\+\([.:0-9A-Fa-f]\+\)/\1/p' /etc/resolv.conf)
if [ -z "$nameservers" ]; then nameservers=empty; fi
networksetup -setdnsservers AirPort $nameservers
share|improve this answer
    
Exercises for budding shell programmers: 1. Why did I deliberately not quote the substitution ($(…) or $nameservers) on the command line of networksetup? 2. How would you write the possibly-empty case as a one-liner? –  Gilles Aug 14 '10 at 22:13
    
I actually managed to work it out my own way before seeing your comment: cat /etc/resolv.conf | grep nameserver | head -n 1 | cut -c 12- | xargs networksetup -setdnsservers AirPort 8.8.8.8 –  Camsoft Aug 16 '10 at 11:20
    
@Camsoft: I recommend adding | grep -v '^ *#' to your pipeline so as to exclude comment lines, and changing cut -c 12- to awk '{print $2}' in case the whitespace on the line changes. –  Gilles Aug 16 '10 at 13:20
add comment

How about something like this:

networksetup -setdnsservers Airport `grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' /etc/resolv.conf`

The regex could probably be improved.

share|improve this answer
    
Wow that's cleaver. Did not know you could do that. So you basically nesting one command in another? –  Camsoft Aug 14 '10 at 21:54
    
Yeah, it's known as "Command Substitution". Very handy to know. –  AdamW Aug 14 '10 at 22:05
1  
@Camsoft: Learn $(…) rather than the backquotes. They're mostly similar, but backquotes require some careful quoting inside, whereas you can simply write an ordinary piece of shell code inside $(…). –  Gilles Aug 14 '10 at 22:15
add comment

Rather than reading /etc/resolv.conf, I'd use networksetup -getdnsservers to get the current list. Only complication is that if there aren't any assigned, it'll reply "There aren't any DNS Servers set on AirPort" so you have to exclude that from the results.

networksetup -setdnsservers "AirPort" $(networksetup -getdnsservers "AirPort" | egrep "^[.:0-9A-Fa-f]+$") 8.8.8.8
share|improve this answer
    
Yeah I thought about this but the problem is I need to include default DHCP assigned DNS servers. When the DNS is assigned by DHCP querying the assigned DNS servers via above command returns none. The resolv.conf includes DHCP assign ones. –  Camsoft Aug 15 '10 at 21:58
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.