Leon Chung

What's my name?

At my current job, we name our computers the same name as their DNS names.

I needed a way to set my Macs' HostName, LocalHostName, and ComputerName the same as the DNS name so that puppet is happy, ARD is happy, and other network things.

I had been trying to name our computers properly via a script and it worked sometimes. I had great help from frogor and a lot of these came from his amazing brain.

At first, we started out with:

ipadd=$(ifconfig | grep "inet " | grep -v | cut -d\  -f2)
hostid=$(dig +short -x "$ipadd" @${DNSIP} | cut -d'.' -f1)
scutil --set ComputerName "$hostid"
scutil --set LocalHostName "$hostid"
scutil --set HostName "$hostid"

We ran ifconfig to get all the IP Address, grep the IPv4 IPs, removed the loopback and took out the extra information.

This worked, or so I thought. Before I go on further, I was getting slapped by someone that I should be using awk and sed. Now, I can barely use grep as it is so I attempted to use awk.

ipadd=$(ifconfig | awk '/inet / {print $2;}' | grep -v

This combined 1 grep and 1 cut command, and I learned awk just a little bit for this excerise.

However, this worked great if the user was only connected on a single interface.

In our network, when a user connects to Ethernet and WiFi, they appear with the same IP Address. I am not sure how this BIND sorcery works, but it works with some CNAME magic that I don't quite understand yet. The problem I was having is that if a user is connected to both, I will get 2 IPs in the variable and only need one and it doesn't matter which, in our case. So frogor came up with this command:

ipconfig getifaddr $(echo 'show State:/Network/Global/IPv4' | scutil | awk '/PrimaryInterface/ {print $3;}') 2>/dev/null

First, we are now going to use the ipconfig command, with the getifaddr option. You would generally run ipconfig getifaddr en0. The second part of this command echo a line for scutil's interactive mode (by using no options) and awk the results to get the active primary interface. If nothing is active, ipconfig will complain that the command is missing the interface and throws an error. In the script, we don't want the error so we'll throw it out.

We end up with something like this, plug in your DNS' IP Address for dig:

# Change hostname to DNS name

# Get IP Address from Primary Interface
ipadd=$(ipconfig getifaddr $(echo 'show State:/Network/Global/IPv4' | scutil | awk '/PrimaryInterface/ {print $3;}') 2>/dev/null)

# Set names based on DNS
if [ -z "${ipadd}" ]; then
    exit 1
    hostid=$(dig +short -x "${ipadd}" @${DNSIP} | cut -d'.' -f1)
    scutil --set ComputerName "${hostid}"
    scutil --set LocalHostName "${hostid}"
    scutil --set HostName "${hostid}"

exit 0

This was important for me because some computers did not have any HostName set and puppet was failing for them. I was also using this before binding machines to Active Directory so they have a proper name.

ip address hostname dns terminal bash ipconfig ifconfig awk