32

I'm curious if it's possible to specify an envrionment variable in the ProgramArguments portion of a luanchd script on Mac OS X Leopard.

<?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>me.mpietz.MountDevRoot</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>

        <string>$HOME/bin/attach-devroot.sh</string>

        <!-- Instead of using...
        <string>/Users/mpietz/bin/attach-devroot.sh</string -->
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
matpie
  • 453
  • 1
  • 5
  • 9

4 Answers4

28

Not in the ProgramArguments key. You need to add an EnvironmentVariables key into your plist's dict like so:

<?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>EnvironmentVariables</key>
    <dict>
           <key>AN_ENVIRONMENT_VARIABLE_NAME</key>
           <string>the_value</string>
    </dict>
    <key>Label</key>
    <string>me.mpietz.MountDevRoot</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>

        <string>$HOME/bin/attach-devroot.sh</string>

        <!-- Instead of using...
        <string>/Users/mpietz/bin/attach-devroot.sh</string -->
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

See: Creating Launch Daemons and Agents.

kenorb
  • 5,943
  • 1
  • 44
  • 53
Joe Block
  • 696
  • 4
  • 12
  • 4
    Sure, you can hard code your env. vars in the plist, but you can't use existing vars like $HOME. Unless it's just an argument to a shell script, in which case the shell (not launchd), will expand it. But in this example, it might actually work if you add the `-c` option to /bin/sh ? – mivk Jul 12 '12 at 20:04
6

The best way to handle this is by wrapping your command in a shell. For example:

<?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>sh.daniel.envvar</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/zsh</string>
        <string>-c</string>
        <string>echo 'You did the thing!' > $HOME/did-the-thing.log</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
❯ cat ~/did-the-thing.log
You did the thing!

The flag -c tells ZSH (and Bash, and sh) to run the command specified in your next. If you add the flag -l, it’ll load your dotfiles before executing, just as a normal login shell does.

  • Thank you for your mention of `-l`! That's the piece I was missing... I have some paths in my .profile that weren't there until I added the `-l` option. – Jesse Apr 04 '22 at 18:42
  • Note: `/bin/sh` does not support `-l` option. At least not on my system. – Jesse Apr 04 '22 at 20:09
3

I don't think launchd knows about the environment natively, at least not as ${VARIABLE} substitutions.

There's nothing stopping you from launching a shell script (or a shell with -c) as your launchd action though, and that would have an environment and respect ${VARIABLES} -- Be aware of the difference between System and User daemons/agents in that case though...

voretaq7
  • 79,345
  • 17
  • 128
  • 213
1

I'm not sure - I haven't tried it before... but I can tell you that if the only variable you care about is home - you can use ~.

So: <string>~/bin/attach-devroot.sh</string>
Dave Holland
  • 1,898
  • 1
  • 13
  • 17
  • 1
    This doesn't work. I get `"/bin/sh: ~/bin/attach-devroot.sh: No such file or directory"` – matpie Feb 17 '10 at 00:56
  • This only works if the `EnableGlobbing` flag is set to true. See the [launchd.plist](https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man5/launchd.plist.5.html#//apple_ref/doc/man/5/launchd.plist) man page. – sakra Jun 02 '12 at 18:45
  • 2
    `EnableGlobbing` not supported anymore – Liviu Jun 27 '18 at 13:19