I’m a big fan of using launchd to automate things in Mac OS X. That serves me well, as that’s how Apple wants things done moving forward. That said, one of launchd’s biggest shortcomings is a lack of a dependency system. There is currently no way, for instance, to specify in a LaunchDaemon’s property list that the daemon requires the network to be active in order to run. This is problematic for some things, such as a script I wrote to automatically set the computer’s hostname based on the DNS server (more on that later). Luckily, Apple has already defined a function, CheckForNetwork
, in /private/etc/rc.common
. Here it is in all its glory:
## # Determine if the network is up by looking for any non-loopback # internet network interfaces. ## CheckForNetwork() { local test if [ -z "${NETWORKUP:=}" ]; then test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l) if [ "${test}" -gt 0 ]; then NETWORKUP="-YES-" else NETWORKUP="-NO-" fi fi }
In your code, simply include rc.common
, then call CheckForNetwork
as needed. An example:
#!/bin/bash # Example Daemon Starter . /etc/rc.common CheckForNetwork while [ "${NETWORKUP}" != "-YES-" ] do sleep 5 NETWORKUP= CheckForNetwork done # Now do what you need to do.
Note that this will keep the script running indefinitely until CheckForNetwork
sets NETWORKUP
to “-YES-
,” so if there’s a networking problem your code may never execute.
Great post! I was able to create my own LaunchDaemon that wakes my NAS whenever I boot up my Mac thanks to your shell script.
Cheers,
Jan