45

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

4
  • 2
    I'm voting to close this question as off-topic because it is an OS question (scheduling a task) rather than a programming question. Your question may be better suited for Ask Different or Super User instead. Commented Apr 26, 2016 at 2:28
  • 1
    Do not use cron, it has been deprecated. Apple's documentation for scheduling jobs describes how you do this with launchd Commented Apr 26, 2016 at 8:30
  • When you say cron has been deprecated, does that mean it no longer works? Commented Jul 11, 2020 at 2:41
  • 1
    @Cauder cron still works on macOS (as of macOS 11 Big Sur 2020). It's fine to use to cron. Apple's documentation says "In OS X, you can run a background job on a timed schedule in two ways: launchd jobs and cron jobs. (Older approaches, such as at jobs and periodic jobs are deprecated and should not be used.)" Commented Jun 14, 2021 at 16:37

4 Answers 4

44

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Who knows if it'll be up for the long-term, but here's a nice launchd tutorial - launchd.info
Compared to cron this is hilariously tedious seeming ;-)
@agathodaimon, Yes, simple is better. But only until you need the feature enhancements. launchd support for sleep mode and more complex time conditions makes it a better solution for many use cases.
@ikanab Not quite sure all the great features justifies the big file approach, bit okiedokie :)
I called osascript directly (here, I'm muting, but the idea is the same). <array> <string>osascript</string> <string>-e</string> <string>set volume output muted true</string> </array>
|
32

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

6 Comments

@Naboo, please mark my answer as right if it was useful. Thanks in advance.
As stated in Apple's documentation "Although it is still supported, cron is not a recommended solution. It has been deprecated in favor of launchd."
No need to create a separate bash script to run an applescript command or script. See stackoverflow.com/questions/36854193/…
this is dumb, but what does the -l flag do please?
Causes bash to run as though it were a login shell. --I (lowercase "I") There is a obviously typo
|
6

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).

1 Comment

Don't forget to give Full Disk Access to Terminal! See Settings -> Security & Privacy.
0

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 }'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.