Naboo
Naboo

Reputation: 451

Scheduling a terminal command or script file to run daily at a specific time Mac OS X

I want to have my computer set its volume to a specific level every night at 11:45 PM. I'm running OSX 10.11.4. I can set the volume manually through terminal with

osascript -e "set Volume 1.7"

or as a script with

set volume 1.7

I want it to be scheduled nightly though. It's hard to find anything online that isn't super outdated. I don't really want to use iCal. From what I've found online, launchd is the way to go, but as a noob, I don't know where to start.

I see things about using a .plist in /Library/LaunchAgents. So I found a nifty plist generator Launched.zerowidth.com but what kind of code do I put in the plist to get the desired effect? I'm also questioning if this is the correct path for this to execute if any user is logged on.

Am I going down the wrong path here? I'm open to any ideas to make this happen, but I don't want to use a 3rd party app that I have to keep open all the time.

Thanks,

Naboo

Upvotes: 45

Views: 74680

Answers (4)

ThatXliner
ThatXliner

Reputation: 514

The top answer is kind of old as launchctl load is marked as a legacy subcommand in favor of launchctl enable.

The first 2 steps are the same: save the following as servicename.plist in ~/Library/LaunchAgents:

<?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>servicename</string>
        <key>ProgramArguments</key>
        <array>
                <string>osascript</string>
                <string>-c</string>
                <string>"set volume 1.7"</string>
        </array>
        <key>StartCalendarInterval</key>
        <dict>
                <key>Hour</key>
                <integer>23</integer>
                <key>Minute</key>
                <integer>45</integer>
        </dict>
</dict>
</plist>

But to enable this, you must run launchctl enable user/502/servicename where 502 is your user UID. Run the following command to find out your user UID:

echo "show State:/Users/ConsoleUser" | scutil | awk '/kCGSSessionUserIDKey :/ { print $3 }'

Upvotes: 0

wisbucky
wisbucky

Reputation: 37827

For a simple one liner, use cron:

# edit your user crontab
crontab -e

# run daily at 20:00 (8:00pm)
0 20 * * * osascript -e "set Volume 1.7"

For a longer script, you can save it as an applescript (.applescript plain text or .scpt binary). Then call it from cron:

# edit your user crontab
crontab -e

# run daily at 20:00 (8:00pm)
0 20 * * * osascript /path/to/setvolume.applescript

Pro Tip:

To avoid the Terminal.app would like to administer your computer prompts every time you edit crontab, you can go to System Preferences > Security & Privacy > Privacy > Full Disk Access and add /Applications/Utilities/Terminal.app.


Note:

While Apple documentation says launchd is preferred over cron, cron is still fully supported thus far even though it's been "deprecated" for years. It's fine to use cron until it's actually removed (which may be never).

Upvotes: 6

retgoat
retgoat

Reputation: 2464

Please consider using the cron daemon. It is present in osx by default.

Create script for volume adjusting

#!/bin/bash -l
/usr/bin/osascript -e "set Volume 1.7"

Then add new line to crontab.

crontab -e

By default, it will open in the vi(m) editor. But you can adjust the default editor with

export EDITOR=/path/to/your/awesome/editor

Then add new string to crontab

0 20 * * * /path/to/volume/script.sh

The given command will run every day at 8 pm.

Please find more crontab examples here: https://en.wikipedia.org/wiki/Cron

Upvotes: 32

Miles
Miles

Reputation: 677

As @TheDarkKnight points out, cron has been deprecated in favor of launchd.

To use launchd, save the following as com.example.volume.plist in ~/Library/LaunchAgents/:

<?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.example.volume</string>
        <key>ProgramArguments</key>
        <array>
                <string>sh</string>
                <string>-c</string>
                <string>set volume 1.7</string>
        </array>
        <key>StartCalendarInterval</key>
        <dict>
                <key>Hour</key>
                <integer>23</integer>
                <key>Minute</key>
                <integer>45</integer>
        </dict>
</dict>
</plist>

then run launchctl load ~/Library/LaunchAgents/com.example.volume to start. You can force the task to run immediately via launchctl start com.example.volume.

If you prefer to have it run as root, save to /Library/LaunchDaemons/ instead.

Upvotes: 44

Related Questions