0

I have a small shutdown script, if the Mac runs over 24 hours it will shutdown. I'm not really experienced in bash scripts, but I did this:

!/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

now i get this error message:

./shutdown: line 9: (: days,: integer expression expected

Anybody can help?

3 Answers 3

1

This should work for macOS. We get the boot timestamp, then the current timestamp in seconds then some math and voila.

#!/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
   shutdown -h now
fi
5
  • Can I enter a name of a specific Mac? for example I want to shutdown the mac121 instead of my mac where this script runs
    – Gunter
    Nov 17, 2016 at 15:30
  • @Gunter you mean another computer altogether? This gets the uptime for the current system. You would copy this program to that computer and run it on that computer. Nov 17, 2016 at 15:31
  • yes (i work with multiple Macs and PCs) So my current PC is Mac298, but at a certain time I want to run the script on a pcwith the name Mac111 instead of mine, without touching that computer, just running it from mine (theyre connected and an SSH connection is possible)
    – Gunter
    Nov 17, 2016 at 15:33
  • Just scp the script to that computer and run it with sudo. scp shutdown.sh user@Mac111: then ssh user@Mac111 "sudo ./shutdown.sh" Nov 17, 2016 at 15:40
  • so the script itself works, but when I start the script through an executable it doesnt shutdown my Mac.. It just says shutdown: NOT super-user logout Saving session... ...copying shared history ...saving history...truncating history files... ...completed. and that's it. Nothing else happens (the Mac is definitely more han 24 hours online) If I start it on a remote Mac, it of course also won't work.. Any ideas?
    – Gunter
    Nov 28, 2016 at 8:53
0

The major bug in your script is cut should look like:

uptime_days=`uptime | cut -d " " -f 4`

Note the 5 became a 4. This is because the cut was picking out the word days, not the number before it.

The way to catch errors like this is to add an echo into your code like:

echo uptime_days=$uptime_days

So when the output contains

uptime_days=days,

it is obvious some error in parsing has occurred.

There are also a couple of other things that could be improved to avoid issues later:

shebang

The top line of the script should start with #! for it to be read by the kernel. Your code is being interpreted by the shell anyway, but if you run the command in a different way it might not so making the top line look like

#!/bin/bash

is a good idea.

double brackets

Using double brackets for conditionals in the shell is less error prone. You can also move the then onto the same line with the if like so:

if [[ $uptime_days -ge $max ]]; then 
     echo shutdown!
fi
2
  • The problem with this approach is that the output of uptime changes depending on how long the machine is up, so for example my computer has been up for 1 minute (Yes I just rebooted). The output of uptime is 10:13 up 1 min, 12 users, load averages: 4.31 1.51 0.58 your cut command will now say that my Mac has been up for 1 day. (there is a double space between the time and the word "up"). Nov 17, 2016 at 16:28
  • I agree there are other issues with the script, but I felt like your answer missed the immediate issue he was having and how to avoid it in general. You provided a solution to his overall problem without helping him understand how to script better or why parsing uptime is a bad idea.
    – chicks
    Nov 17, 2016 at 16:32
-2

This is the whole script:

#!/bin/bash
uptime | grep -q days && shutdown -h now
1
  • tried it, now it says that the "fi" is unexpected
    – Gunter
    Nov 17, 2016 at 15:17

You must log in to answer this question.

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