I have a ~/Library/LaunchAgents/setenv.JAVA_HOME.plist
file which contains a /bin/launchctl
call as follows:
<?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>setenv.JAVA_HOME</string>
<key>ProgramArguments</key>
<array>
<string>/bin/launchctl</string>
<string>setenv</string>
<string>JAVA_HOME</string>
<string>$(/usr/libexec/java_home -v1.8)</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
Problem is, the $(/usr/libexec/java_home -v1.8)
expression is not evaluated and instead the JAVA_HOME
environment variable is assigned the literal value $(/usr/libexec/java_home -v1.8)
.
Question is: is it possible to compose my plist file so that the expression is evaluated and not treated as a literal value? And, if so, how?
As you've discovered, <string>
entries are passed as string literals, but $(/usr/libexec/java_home -v1.8)
is a bash shell expression. According to the launchd.plist documentation, ProgramArguments
only takes an array of strings, so there does not appear to be any way of marking an argument as an expression.
However, I think the simple solution is to run /bin/bash
with the -c
argument, followed by the command line you want to execute.
<?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>test.so</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/bin/launchctl setenv JAVA_HOME $(/usr/libexec/java_home -v1.8)</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>