Auto-Update Script

bashserver.appsshterminalunix

I'm trying to get the Macs at my workplace all updating at a specific time. To do so, I'm running a bash script from a spare Macbook running OS X Server. I have one minor and one big issue with my current script, and could use your help.

The script is very simple, and I don't need it to be too robust for my purposes:

#!/bin/bash
for host in 192.blah.blah.blah 192.blah.blah.blah 192.blah.blah.blah
do
ssh -t $host sudo softwareupdate -ia
ssh -t $host sudo shutdown -r now
done

The minor issue: for whatever reason, if I try to put both of those commands on the same line using ; or && like so:

ssh -t $host sudo softwareupdate -ia;sudo shutdown -r now

or

ssh -t $host sudo softwareupdate -ia && sudo shutdown -r now

it reboots the actual server instead. Not sure where I'm going wrong with the syntax.

The big issue: Despite setting up ssh with a public ssh key (using the instructions I found here), I'm still asked to input a password twice per machine when the script runs. I'm positive it's due to our friend sudo, but the commands don't run at all without it. Ideally, I'll set up a cron job at an early point in the morning and have it run this script automatically so that by the time I'm at work, the Macs will have updated and rebooted. I'm sure there is a way to do it, but my Google-Fu is failing me.

EDIT/PARTIAL ANSWER
Turns out, even if you put TextEdit into Plain Text mode, it's still using 'smart quotes'. Typing out and saving the script through the Terminal and THEN running it worked like a charm.

0942v8653 was kind enough to help me out in chat, and also provided a command to disable this 'feature': defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false

Still looking for a solution to the password issue.

Best Answer

The ; and && are interpreted by bash on the local machine. You can see this by running ssh 127.0.0.1 -t env && env: the second time, there will be no SSH_CONNECTION variable.

You can quote the entire command to get it to work properly:

ssh -t $host 'sudo softwareupdate -ia && sudo shutdown -r now'

In my opinion, -t should only allow one, quoted, argument to avoid problems like this…also beware of variable expansion—make sure to put everything in single quotes or escape it with backslashes to keep it from being expanded or interpreted on the local machine.