MacOS – How to reset OS X volume after sleep using launchd

applescriptlaunchdmacos

I'm been trying to write a plist file on which when I return from sleep mode, I always want to make my Mac volume to the minimum amount. However, it looks like the following plist doesn't work, with an error: 1:1: syntax error: Expected string but found end of script. (-2741)

<?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>KeepAlive</key>
        <false/>
        <key>Label</key>
        <string>my.plist</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/bin/osascript</string>
            <string>-e</string>
            <string>"</string>
            <string>set</string>
            <string>volume</string>
            <string>output</string>
            <string>volume</string>
            <string>0</string>
            <string>"</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

Also, when the following is not working:

<?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>KeepAlive</key>
        <false/>
        <key>Label</key>
        <string>my.plist</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/bin/osascript</string>
            <string>-e</string>
            <string>"set volume output volume 0"</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

The osascript command functions well if I execute it from within Terminal, so I think it's due to how I set my arguments list to the plist.

So is it feasible to take the string argument like "~" in launchd? Or is there some other things that I'm missing here?

I suspect that it might be better to write the osascript command in shell script, and load the shell script to enable the Mac's volume to minimize… but is it the correct approach?

I use OS X Mavericks 10.9.2.

Best Answer

The second launchd job ticket format is almost correct. Only a set of quotes need removing.

Quotes

The quotes are no longer needed in the second launchd job ticket, so change:

<string>"set volume output volume 0"</string>

…to…

<string>set volume output volume 0</string>

Grouping Arguments

In this case, the quotes grouped the set of arguments for osascript to see as one item. Thus osascript gets two arguments, the flag -e and the script. This meets the requirements from the osascript manual.

When called through Terminal.app and thus through the shell, the quotes are needed to perform the grouping. When osascript gets the arguments, the shell has removed the quotes.

Without quotes, spaces subdivide each item passed via the shell.

When called through a launchd job ticket, the grouping is intrinsic within the array passed as ProgramArguments. In your first ticket, the array contained nine items and in the second ticket, the array contained three.

LaunchAgent

Be sure to add this launchd job as a ~/Library/LaunchAgents as osascript requires an active user with a graphical session.

This approach approximates what I do with Power Manager in How to Set the Volume When Logging In.