Update:
Added the ability to ignore specific IP addresses (smart switch and printer in my case) so for example if you forget to turn off the printer, it doesn’t prevent the NAS from spinning down as well.
Also made a version that logs status changes, tested over night. This works really well. I’m inclined to say that this can be considered pretty much “production” now.
Stripped down version with logging code removed (not really needed, except for testing that it works!).
If you have any smart switches or similar non-computer-stuff on your LAN that stays powered on 24/7 and that might respond to nmap, put their addresses into $IGNORE, otherwise set $IGNORE to empty.
#!/bin/sh
# 192.168.178.13 = NetGear GS108E
# 192.168.178.14 = HP LaserJet 2050N
IGNORE=192.168.178.13,192.168.178.14
PATH=/bin:/sbin:/opt/bin:/usr/bin:/usr/sbin
MARKER=/tmp/autoshutdown_marker
if hdparm -C /dev/sda | grep -q "standby" ; then
exit 0
fi
sync
if [[$IGNORE]] ; then
IGNORE="--exclude $IGNORE"
fi
MYIP=$( ifconfig eth0 | grep "inet " | cut -d: -f2 | cut -d " " -f1 )
NETWORK=$( echo "$MYIP" | cut -d. -f-3 )
CLIENTS=$NETWORK.0/24
ROUTERIP=$( route -n | grep ^0.0.0.0 | awk '{print $2;}' ),$NETWORK.254
if nmap -snPP $CLIENTS $IGNORE --exclude $MYIP,$ROUTERIP | grep -q "\(0 hosts up\)" ; then
if test -f $MARKER ; then
rm $MARKER
sleep 2
hdparm -y /dev/sda
exit 0
else
touch $MARKER
fi
else
if test -f $MARKER ; then
rm $MARKER
fi
fi
Original version with logging functionality for debugging (in fact, simply changing $LOGFILE to /dev/null would probably have been more elegant than stripping out the logging):
#!/bin/sh
# ignore HP LaserJet
# ignore NetGear GS108E
IGNORE=192.168.178.13,192.168.178.14
PATH=/bin:/sbin:/opt/bin:/usr/bin:/usr/sbin
MARKER=/tmp/autoshutdown_marker
LOGFILE=/tmp/autoshutdown_log
if hdparm -C /dev/sda | grep -q "standby" ; then
date +"%Y %m %d %R : [standby]" >> $LOGFILE
exit 0
fi
sync
if [[$IGNORE]] ; then
IGNORE="--exclude $IGNORE"
fi
MYIP=$( ifconfig eth0 | grep "inet " | cut -d: -f2 | cut -d " " -f1 )
NETWORK=$( echo "$MYIP" | cut -d. -f-3 )
CLIENTS=$NETWORK.0/24
ROUTERIP=$( route -n | grep ^0.0.0.0 | awk '{print $2;}' ),$NETWORK.254
if nmap -snPP $CLIENTS $IGNORE --exclude $MYIP,$ROUTERIP | grep -q "\(0 hosts up\)" ; then
if test -f $MARKER ; then
rm $MARKER
sleep 2
date +"%Y %m %d %R : still no hosts up ---> entering standby mode" >> $LOGFILE
hdparm -y /dev/sda
exit 0
else
date +"%Y %m %d %R : no hosts up" >> $LOGFILE
touch $MARKER
fi
else
if test -f $MARKER ; then
date +"%Y %m %d %R : hosts detected" >> $LOGFILE
rm $MARKER
fi
fi
Output from last night, running */5 * * * * from crontab, comments in bold :
NAS:~# cat /tmp/autoshutdown_log
2013 01 23 20:30 : no hosts up (turned off computer at 20:28)
2013 01 23 20:35 : still no hosts up ---> entering standby mode
2013 01 23 20:40 : [standby]
2013 01 23 20:45 : [standby]
2013 01 23 20:50 : [standby]
2013 01 23 20:55 : [standby]
2013 01 23 21:00 : [standby]
...
2013 01 24 02:55 : [standby] (cron.daily runs here)
2013 01 24 03:05 : no hosts up
2013 01 24 03:10 : still no hosts up ---> entering standby mode
2013 01 24 03:15 : [standby]
2013 01 24 03:20 : [standby]
2013 01 24 03:25 : [standby]
...
2013 01 24 04:00 : [standby]
2013 01 24 04:05 : no hosts up
2013 01 24 04:10 : still no hosts up ---> entering standby mode
2013 01 24 04:15 : [standby]
2013 01 24 04:20 : [standby]
2013 01 24 04:25 : [standby]
2013 01 24 04:30 : [standby]
2013 01 24 04:35 : [standby]
...
2013 01 24 07:35 : [standby] (turn on computer for work)
As can be seen the disk wakes twice during the night: once when cron.daily runs and once an hour later. cron. daily runs, among other things, htcacheclean, updates apt and aptitude, checks for firmware updates, backs up samba config, and writes ramlog to disk. Further, the aptitude update script sleeps for a random amount of time from 30 min to 1 hour in the middle (for some obscure reason).
What we see happening here is thus entirely well-explained.
Two spin-up/spin/down cycles per night is very acceptable, in my opinion.