1

So I have this script to shutdown Macs after 24 hours runtime.

#!/bin/bash

my_macs=( Mac1 Mac2 Mac3 )

MAX_UPDAYS=1

CURR_TIME=$(date +%s)
MAX_UPTIME=$(( MAX_UPDAYS * 86400 ))
ADMINUSER="pcpatch"


echo "Remote Shutdown Check vom $(date)"  | tee -a /Users/admin/Shutdown/Log/Shutdown 2>&1
for MAC in "${my_macs[@]}"
do
    echo -n "Überprüfe ${MAC}... "

    if /sbin/ping -q -c3 "${MAC}" >/dev/null; then 
        echo "${MAC} ist angeschaltet. Laufzeit wird ermittelt... "

        BOOT_TIME=0
        BOOT_TIME=$(ssh "${ADMINUSER}@${MAC}" sysctl -n kern.boottime | sed -e 's/.* sec = \([0-9]*\).*/\1/')

        if [ "$BOOT_TIME" -gt 0 ] && [ $(( CURR_TIME - BOOT_TIME )) -ge $MAX_UPTIME ]; then
            echo "${MAC} ist über 24 Stunden online. Shutdown wird ausgeführt!"
            ssh "${ADMINUSER}@${MAC}" 'sudo /sbin/shutdown -h now'
        else
            echo "${MAC} ist noch keine 24 Stunden online. Shutdown wird abgebrochen!"
        fi

    else
        echo "${MAC} ist nicht erreichbar (Ping fehlgeschlagen)" 
    fi

done | tee -a /Users/pcpatch/Shutdown/Log/Shutdown 2>&1
echo " "  | tee -a /Users/pcpatch/Shutdown/Log/Shutdown 2>&1

When I run it through the terminal it works fine, Macs that are online more than 24 hours shut down, everything else does nothing.

So far so good, but I want to run this script through a cronjob everyday at 23:00 o'clock. So I made this cronjob:

00 23 * * * /Users/admin/Shutdown/Shutdown.sh

Now the script runs everyday, the cron line itself works. The Macs won't shutdown though and the log just says that the Macs did not run more than 24 hours. Though I frequently have Macs that run more than 3-4 days.

Does anyone know how to solve this problem?

Edit: I added $BOOT_TIME and $CURR_TIME to the log, and it gives out somehing like this: 1492549200 as CURR_TIME and nothing as the BOOT_TIME, though the Mac was definitely running, as he is right now (6 days online). This Mac has OSX Sierra installed though and one other Mac (with OS X El Capitan) put BOOT_TIME as 1492505076 and CURR_TIME as 1492549200

I really don't know what these number could mean though...

6
  • Please add logging for $BOOT_TIME, $CURR_TIME and other values of interest, then come back >24h later and add the values to the question.
    – nohillside
    Commented Apr 18, 2017 at 10:39
  • @patrix I will do that!
    – Gunter
    Commented Apr 18, 2017 at 11:04
  • 1
    My assumption is that BOOT_TIME doesn't get set because ssh (silently) fails. Are you running the cronjob from the same user as you do through Terminal? Or does the cronjob belong to root but you manually run it as an admin user?
    – nohillside
    Commented Apr 18, 2017 at 11:07
  • I used sudo crontab -e, so I suppose it should be running as root I tried it with different users through the terminal though and they both worked (my own admin and with the sudo command)
    – Gunter
    Commented Apr 18, 2017 at 11:19
  • 1
    Why reboot ? - what problem are you trying to solve?
    – mmmmmm
    Commented Apr 18, 2017 at 11:30

1 Answer 1

1

Your script doesn't fetch the BOOT_TIME of the remote hosts properly in the cron environment.

I recommend to remove the cronjob and create a launch agent usr.remoteshutdown.plist instead in /Users/admin/Library/LaunchAgents/ with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>Label</key>
    <string>usr.remoteshutdown</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/admin/Shutdown/sh/remoteshutdown.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>23</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
</dict>
</plist>

Then load the launch agent by entering in the Terminal.app:

launchctl load /Users/admin/Library/LaunchAgents/usr.remoteshutdown.plist

Please adjust the (admin) user name and the name and location of the shutdown script in the plist.


To test this you don't have to wait 24 hours. Simply either

  • remove the sudo in the shell script temporarily
  • comment out the line ssh "${ADMINUSER}@${MAC}" 'sudo /sbin/shutdown -h now'
  • comment out the ssh ... shutdown -h now line and insert a line echo "Boot: ${BOOT_TIME}"
  • echo the ssh ... shutdown -h now line (instead of executing it)

Then modify StartCalenderInterval in the launch agent to a point of time in the near future (current time +3 minutes). Unload and load the plist with:

launchctl unload /Users/admin/Library/LaunchAgents/usr.remoteshutdown.plist
launchctl load /Users/admin/Library/LaunchAgents/usr.remoteshutdown.plist

The shell script requires SSH key-based authentication and that the admin has a special line in the sudoers files of the remote hosts to allow sudo shutdown ... without entering passwords!

3
  • The admin can shutdown without enteringa password, I already did these settings. Like I said, the script works fine, without any passwords when I run it through the terminal. I never used the launch agent, so where should I put this line: launchctl load /Users/admin/Library/LaunchAgents/usr.remoteshutdown.plist? In the crontab?
    – Gunter
    Commented Apr 19, 2017 at 6:32
  • @Gunter In Terminal.app. launchctl is a cl tool. The PS (sudoers file...) is just a reminder for other users applying your shutdown script to their environment
    – klanomath
    Commented Apr 19, 2017 at 12:02
  • Ah ok thank you. I will give you more details tomorrow, because the Macs are working right now.
    – Gunter
    Commented Apr 19, 2017 at 12:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .