Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Keep apps alive without losing environment variables System
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: Remember to adjust the paths and filenames as appropriate.

[robg adds: I haven't tested this one.]
    •    
  • Currently 1.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (5 votes cast)
 
[8,576 views]  

Keep apps alive without losing environment variables | 2 comments | Create New Account
Click here to return to the 'Keep apps alive without losing environment variables' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Keep apps alive without losing environment variables
Authored by: momerath on Oct 20, '08 08:38:37AM
Couldn't you just run bash -l [CMD]? That executes [CMD] with all of your login and environmental variables I believe.

[ Reply to This | # ]
Keep apps alive without losing environment variables
Authored by: nxg on Oct 29, '08 08:58:22PM

No, that doesn't work, because the content of ~/.MacOSX/environment.plist is processed by loginwindow, to change its own environment, and not as any part of shell startup (note); thus /bin/sh -l has no effect here.

There is an alternative mechanism, however, which is a lot neater. Go back to the original launchd Property List file to keep Quicksilver alive – the one with the single argument, described elsewhere. Then consider the following script:

#! /bin/sh -
#
# For each of the environment variables defined in ~/.MacOSX/environment.plist,
# inject it into the environment of launchd.
#
# Norman Gray <http://nxg.me.uk>

cat <<EOD | /usr/bin/xsltproc --novalid - $HOME/.MacOSX/environment.plist | sh
<?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'/>
  </template>
  <template match='key'>launchctl setenv <value-of select='.'/> <value-of select='following::string[1]'/>;</template>
</stylesheet>
EOD

exit 0

Put that in ~/Library/LaunchAgents/environment-to-launchd.sh and make it executable. What this does is to work through the environment.plist file, getting launchd to set each of the variables within its own environment. In consequence, any child processes started by launchd (in the case we're interested in, that means Quicksilver) inherit those environment variables. Which is what we want.

But the problem is: how do we get this script run promptly after logging in. That's easy – we use launchd.

Create another launchd property list, which looks like:

<?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>RunAtLoad</key>
	<true/>
	<key>Label</key>
	<string>nxg.LaunchdEnvironment</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Users/norman/Library/LaunchAgents/environment-to-launchd.sh</string>
	</array>
</dict>
</plist>

(adjusting the path accordingly)

That's it – log out and back in again (or do appropriate launchctl load/unload stuff), and launchd will keep Quicksilver alive, and additionally inject the variable settings within ~/.MacOSX/environment.plist into the launchd process.



[ Reply to This | # ]