Keep apps alive without losing environment variables

Oct 20, '08 07:30:00AM

Contributed by: nxg

Other hints, such as this one, describe how to keep an application alive using launchd. problem with this technique is that applications (re-)started this way inherit launchd's environment, not the user's, and so don't include any environment variables defined in ~/.MacOSX/environment.plist

If that's a problem for you (it is for me), then you can include those variables by launching the application indirectly, from a script which parses the environment.plist before invoking the application. Save the script below to a file called LaunchWithToplevelEnvironment.sh (or whatever you like) in ~/Library/LaunchAgents, then make that script executable (chmod a+x script_name):

#! /bin/sh -
#
# Launch a program (given as the first argument) in an environment
# which includes the variables defined in ~/.MacOSX/environment.plist.
#
# Usage:
#   LaunchWithUserEnvironment.sh <program> arg? ...
#
# Norman Gray <http://nxg.me.uk>

if test $# -eq 0; then
   echo "$0: no args" >&2
   exit 1
fi

tmpfile=${TMPDIR:-/tmp}/nxg.LaunchWithToplevelEnvironment.tmp

cat <<EOD | /usr/bin/xsltproc --novalid - $HOME/.MacOSX/environment.plist > $tmpfile
<?xml version='1.0' encoding='UTF-8'?>
<stylesheet xmlns='http://www.w3.org/1999/XSL/Transform' version='1.0'>
 <output method='text' encoding='UTF-8' version='1.0'/>
 <template match='/'>
   <apply-templates select='plist/dict/key'/>
   <text>
</text>
 </template>
 <template match='key'>
   <text>export </text>
   <value-of select='.'/>
   <text>=</text>
   <value-of select='following::string[1]'/>
   <text>
</text>
 </template>
</stylesheet>
EOD

. $tmpfile
rm -f $tmpfile

# exec the program, including any provided arguments
exec "$@"

# shouldn't get here
exit 1
# end of script
You use it by creating or amending the KeepAlive launchd plist file so that it has a two-argument ProgramArguments element:
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>keepalive.QuickSilver</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/norman/Library/LaunchAgents/LaunchWithToplevelEnvironment.sh</string>
        <string>/Data/LocalApplications/Quicksilver.app/Contents/MacOS/Quicksilver</string>
    </array>
</dict>
</plist>
Remember to adjust the paths and filenames as appropriate.

[robg adds: I haven't tested this one.]

Comments (2)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20081016073426245