1

Can I shutdown multiple Macs in my office (9-10 Macs) in my office after checking their runtime? I have one Mac, which acts as a Server (with the OS Server application). SSH is also enabled on every Mac, so logging on remotely is not a problem. I want to write a script that checks:

if the runtime >=24h then shutdown mac

Now I don't know anything about scripting on a Mac but I've done this before with powershell and windows machines.

Curently I have this script:

#!/bin/bash
BOOT_TIME=$(sysctl -n kern.boottime | sed -e 's/.* sec = \([0-9]*\).*/\1/')
CURR_TIME=$(date +%s)
MAX_UPDAYS=1 #Days

DAYS_UP=$(( ( $CURR_TIME - $BOOT_TIME) / 86400 ))
    if [ $DAYS_UP -ge ${MAX_UPDAYS} ];then
        echo Mac is going to shutdown 
        shutdown -h now
    else
        echo No shutdown needed
fi

but don't know how to run it on the remote Macintoshs

  • I would ask why would you want to do this, Unix boxes work with long uptimes and reboots are not required except in exceptional cases. What is the actual problem you are trying to solve. What happens if the machine is in use which if it is on one reboot then it is likely to be on the next etc. – Mark Nov 15 '16 at 11:42
  • Is this the same issue as apple.stackexchange.com/questions/261021/… ? – nohillside Nov 15 '16 at 13:43
  • Ah, and if you need help in joining your accounts, please use the contact link at the bottom of the page. – nohillside Nov 15 '16 at 13:44
  • The "what to do" is already in the answer, what exactly is unclear? – nohillside Nov 18 '16 at 9:23
  • What do you mean it's in the answer? In the answer of Alan is only how to run it daily, but I want to run it remotely – Gunter Nov 18 '16 at 9:31
0

Note: I was composing my answer to another question/post of yours where you were asking pretty much the same thing but you were using 2 separate scripts. I can't find it now as it was probably deleted as being a duplicate but I hope this answer resolves your issue.

In my opinion, having these as separate scripts just complicates it. Here is a quick rewrite that combines them.

#!/bin/bash

#Array of Mac hostnames separated by spaces
my_macs=( Mac111 Mac121 Mac122 Mac123 Mac124 Mac125 Mac126 Mac127 Mac128 Mac129 )

# Number of days the remote Mac is allowed to be up
MAX_UPDAYS=7

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

#Steps through each hostname and issues SSH command to that host
#Loops through the elements of the Array

echo "Remote shutdown check started at $(date)"
for MAC in "${my_macs[@]}"
do
    echo -n "Checking ${MAC}... "
    # -q quiet
    # -c nb of pings to perform

    if ping -q -c3 "${MAC}" >/dev/null; then
        echo "is up. Getting boot time... "

        BOOT_TIME=0
        # Get time of boot from remote Mac
        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} uptime is beyond MAX_UPDAYS limit.  Sending shutdown command"
            ssh "${ADMINUSER}@${MAC}" 'sudo /sbin/shutdown -h now'
        else
            echo "${MAC} uptime is below limit.  Skipping shutdown."
        fi

    else
        echo "is down (ping failed)"
    fi
done

As for the cron entry

  1. You should always use the full path to the script. Cron jobs don't normally start in the user's home dir so ./documents/ would be the wrong location (it would look for a documents dir from the root of the hard drive).
  2. Redirect the script output to append to a log file. This will record the echo commands to the log file so you know what is happening.

So, change your crontab entry to something like this

30 23 * * * /Users/gunter/documents/remoteshutdown.sh >> /Users/gunter/documents/remoteshutdown.log

And a couple other bash shell tips that I've changed in the script

  • The ping exit code check [ $? -eq 0 ] can be done directly in the if statement.

  • $ is unnecessary on arithmetic variables so $(( $CURR_TIME - $BOOT_TIME )) should be $(( CURR_TIME - BOOT_TIME ))

  • I deleted it myself, because I have asked the same question on the Stack Exchange Ubuntu forum. There I already had an answer that fitted perfectly for me. But your idea is also very good, because it makes it a lot easier for me when it's only one script. I'm going to try it and if it works I will accept your answer. Anyway, thanks for still finding this post, it just shows what a nice community Stack Exchange is. – Gunter Jan 4 '17 at 15:28
  • I tried it out and really need to say that it is perfect. I tested everything and it works perfectly without any bugs. Thank you very much! – Gunter Jan 5 '17 at 8:41
  • I now have a small problem, the script doesn|t log properly. The log file is created, but shows everything that is done on the pc (even the current tim= when I look at the log 2 days later it will show the entrys of today. Any idea how to fix this? – Gunter Jan 12 '17 at 7:11
  • Did you change any part of the script or the crontab line? As it is listed, it should log the date as when it ran, not when you are looking at the log. For example, I just set this up under cron and it ran properly with the log showing Remote shutdown check started at Thu Jan 12 12:18:00 MST 2017 – Insomniac Software Jan 12 '17 at 19:21
  • I don't know why but today it suddenly worked. Weird but I'm fine with it. Thanks again – Gunter Jan 13 '17 at 7:12
0

You can do this with a simple bash script, the uptime command and launchd. If you execute the command by itself, it will tell you how long the machine has been up:

$ uptime
6:08  up 20 days, 21:09, 4 users, load averages: 1.09 1.29 1.36

So, the number that we are interested is the "20" which we will evaluate against our condition of "1 day"

#!/bin/bash

#Maximum number of days to be up
max=1

#Get the uptime days and assign it to a variable
uptime_days=`uptime | cut -d " " -f 5`

if [ $uptime_days -ge $max ]
  then 
  shutdown -h now
fi

exit 0

Make sure you set the script as executable or it won't run:

chmod +x shutdown24.sh

Now, here's the most important part. When do you want to evaluate this? Technically, your could have this script run every hour (or even ever minute) to evaluate if the computer has been up for 24 hours.

This is not recommended because if for some reason the computer was turned on at 10:00am (because the person was late, for example) you don't want it shutting down at 10:00am the next morning when they are in the middle of their work.

So, I'm going to assume you want it run at midnight so you don't inadvertently shutdown the machine while people are working. What you need is to utilize lauchd and create a .plist that defines the job (similar to Task Scheduler) in Windows.

Let's assume that we called the bash script shutdown24.sh so we will call our .plsit com.user.shutdown24.plist

<?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>Label</key>
    <string>com.user.shutdown24</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/USERNAME/Path_to_Scripts/shutdown24.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
    <dict>
        <key>Hour</key>
        <integer>00</integer>
        <key>Minute</key>
        <integer>00</integer>
    </dict>

</dict>
</plist>

Copy this file to /Library/LaunchDaemons and then load it to launchd:

sudo launchctl load com.user.shutdown24.plist

The job will be run as root and at 12:00am every morning, it will check if the system uptime and will shutdown if it's greater than 24 hours.

  • Where do I write that? Directly in the terminal or do I need to put it in an editor somewhere? I'm sorry I never did something like that with a Mac. – Gunter Nov 15 '16 at 12:00
  • The bash file is a script, just like a powershell script, so you can use any text editor to create/modify it and you save it wherever you like. Same with the .plst you can use whatever editor, but ultimately you are going to copy/save it to /Library/LaunchDaemons – Allan Nov 15 '16 at 12:08
  • I just tried to write it in script editor, which is already installed on my mac. I cant save it as a .sh though... I dont know what to do.. – Gunter Nov 15 '16 at 15:42
  • That's AppleScript editor. Try TextEdit or my favorite x-platform editor Komodo Edit which is free. – Allan Nov 15 '16 at 16:15
  • I still can't get it to run, I don't know what I'm doing wrong.. but thanks anyway – Gunter Nov 17 '16 at 9:52

You must log in to answer this question.

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