{"id":34,"date":"2013-11-07T03:17:00","date_gmt":"2013-11-06T17:17:00","guid":{"rendered":""},"modified":"2024-05-13T01:32:42","modified_gmt":"2024-05-12T15:32:42","slug":"setting-environment-variables-in-os-x-yosemite-and-mavericks","status":"publish","type":"post","link":"https:\/\/pbw.id.au\/blog\/2013\/11\/setting-environment-variables-in-os-x-yosemite-and-mavericks\/","title":{"rendered":"Setting environment variables in  MacOS Big Sur"},"content":{"rendered":"<p>This method uses <i>launchctl<\/i> to manage environment variables for programs invoked directly from Finder. \u00a0See the <em>launchctl<\/em> man page, especially the section LEGACY SUBCOMMANDS. \u00a0It&#8217;s not entirely accurate, but that&#8217;s not unusual. \u00a0The critical subcommands are <i>getenv<\/i>, <i>setenv<\/i>, and <i>unsetenv<\/i>. The <i>man<\/i> page indicates that the export subcommand is available; it is not.<\/p>\n<p><!--more-->As far as I know, the procedure outlined below is still valid for Big Sur, but the question is still open. \u00a0I would not be surprised to learn that the behaviour of <em>launchctl<\/em> has changed in ways which invalidate some of this discussion. \u00a0If you find any problems, please let me know in comments.<\/p>\n<p>As explained in a previous post, the now-recommended method of system variable setting is to use the <i>setenv<\/i> subcommand of <i>launchctl<\/i>, like so:<\/p>\n<p><code>launchctl setenv M2 \/usr\/share\/maven\/bin<\/code><\/p>\n<p>The strings defined in setenv statements like the above, must be string literals. There is no means of resolving variable content based on other variables. For example, you cannot define<br \/>\n<code>setenv TMPDIR $HOME\/tmp<\/code><\/p>\n<p>Here&#8217;s the modified code in <i>.profile<\/i> to set both <i>launchctl<\/i> and the bash environment variables.<br \/>\nCreate the following functions in <i>.profile<\/i>.<br \/>\n<code>export LAUNCHCTL_ENV_VARS=\"$HOME\/.launchctl_env_vars\"<br \/>\nif [ -f $LAUNCHCTL_ENV_VARS ] ; then rm $LAUNCHCTL_ENV_VARS; fi<\/code><\/p>\n<p><code>set_launchctl_env () {<br \/>\neval launchctl setenv \"$1\" \\\"\"$2\"\\\"<br \/>\necho launchctl setenv \"$1\" \\\"\"$2\"\\\" &gt;&gt;$LAUNCHCTL_ENV_VARS<br \/>\n}<br \/>\nunset_launchctl_env () {<br \/>\neval launchctl unsetenv \"$1\"<br \/>\necho launchctl unsetenv \"$1\" &gt;&gt;$LAUNCHCTL_ENV_VARS<br \/>\n}<\/code><\/p>\n<p><code>set_env_var () {<br \/>\neval export $1=\\\"\"$2\"\\\"<br \/>\nset_launchctl_env \"$1\" \"$2\"<br \/>\n}<br \/>\nunset_env_var () {<br \/>\nunset $1<br \/>\nunset_launchctl_env \"$1\"<br \/>\n}<\/code><\/p>\n<p>You may then use the function <i>set_env_var<\/i> to set both bash and <i>launchctl<\/i> entries. For example,<br \/>\n<code>set_env_var M2_HOME \"\/usr\/share\/maven\"<br \/>\nset_env_var M2 \"$M2_HOME\/bin\"<br \/>\nset_env_var HTML_TIDY \"$HOME\/.tidy\"<br \/>\n<\/code><br \/>\nN.B. The <em>launchd<\/em> environment variables <strong><em>are distinct<\/em><\/strong> from the shell environment variables. Hence the procedure <em>set_env_var<\/em> sets them both. Note that the environment variables will immediately be available to any shell scripts or Terminal invocations, <i>and<\/i> the <em>launchd<\/em> variables should be immediately available to any applications launched from the desktop. (<em>I&#8217;m trying to confirm this for <\/em>Sonoma.)<\/p>\n<p>To get the environment re-established across a login, the <i>launchctl<\/i> startup features have to be invoked. This is where the file <i>~\/.launchctl_env_vars<\/i> comes in. \u00a0Notice that in the .profile code above, we have been executing a launchctl setenv command, and immediately echoing that same command to <i>~\/.launchctl_env_vars<\/i>.<\/p>\n<p>When the system starts, the <i>launchd<\/i> process finds system daemon processes to launch from <i>\/System\/Library\/LaunchDaemons &amp;<\/i> <i>\/Library\/LaunchDaemons<\/i>. When a user logs in, <i>launchd<\/i> looks for user agents to start up in <i>\/System\/Library\/LaunchAgents<\/i>, <i>\/Library\/LaunchAgents<\/i> &amp; <i>~user\/Library\/LaunchAgents<\/i>. While the first two are system-owned directories, the third is owned by the individual user.<\/p>\n<div>We need two files: 1) a shell script which will actually issue the <i>launchctl setenv<\/i> commands, and 2) a <i>LaunchAgent<\/i> file that will tell <i>launchd<\/i> where to find the executable, and how to run it. The shell script is available <a href=\"http:\/\/pbw.id.au\/profile2launchctl\/profile2launchctl\">here<\/a>; the LaunchAgent file is available <a href=\"http:\/\/pbw.id.au\/profile2launchctl\/pbw.profile2launchctl.plist\">here<\/a>.<\/div>\n<h4>The executable: profile2launchctl<\/h4>\n<p><code><span style=\"color: red;\">#!\/bin\/sh<\/span><br \/>\n#<br \/>\ncmd_list=\"$HOME\/.launchctl_env_vars\"<br \/>\nSLEEP_TIME=10<br \/>\n<span style=\"color: red;\"># Uncomment following to echo launchctl commands to stdout<\/span><br \/>\n<span style=\"color: red;\"># Key StandardOutPath will have to be set in the plist file<\/span><br \/>\n<span style=\"color: red;\"># (pbw.plist2launchctl) for output to be captured.<\/span><br \/>\n<span style=\"color: red;\">#ECHO_TO_STDOUT=true<\/span><br \/>\n#<br \/>\none_cmd () {<br \/>\neval \"$@\"<br \/>\n}<br \/>\n#<br \/>\n[[ -n \"$ECHO_TO_STDOUT\" ]] &amp;&amp; cat \"$cmd_list\"<br \/>\ncat \"$cmd_list\" | while read line; do one_cmd $line; done<br \/>\n[[ -n \"$ECHO_TO_STDOUT\" ]] &amp;&amp; echo Sleeping in profile2launchctl<br \/>\n#<br \/>\n[[ -n \"$SLEEP_TIME\" ]] &amp;&amp; sleep \"$SLEEP_TIME\"<\/code><br \/>\n<i>Notes:<\/i><br \/>\nThe required sequence of <i>launchctl setenv<\/i> is in the <i>cmd_list<\/i> file. The commands are simply read one line at a time,\u00a0 and each line is handed to <i>eval<\/i> for execution.<br \/>\n<i>Permissions &amp; Location:<\/i><br \/>\nTo stay on the safe side, give the file -rwxr-xr-x permissions. The locations is as specified in the plist file, which must be edited to reflect this location, and the label you apply. See following description.<\/p>\n<h4>The LaunchAgent file: pbw.profile2launchctl<\/h4>\n<p><code>&lt;? xml version=\"1.0\" encoding=\"UTF-8\"?&gt;<br \/>\n&lt;!DOCTYPE plist PUBLIC \"-\/\/Apple\/\/DTD PLIST 1.0\/\/EN\" \"http:\/\/www.apple.com\/DTDs\/PropertyList-1.0.dtd\"&gt;<br \/>\n&lt;plist version=\"1.0\"&gt;<br \/>\n&lt;dict&gt;<br \/>\n&lt;key&gt;Label&lt;\/key&gt;<br \/>\n&lt;string&gt;pbw.profile2launchctl&lt;\/string&gt;<br \/>\n&lt;key&gt;KeepAlive&lt;\/key&gt;<br \/>\n&lt;false\/&gt;<br \/>\n&lt;key&gt;Program&lt;\/key&gt;<br \/>\n&lt;string&gt;{location you choose}\/profile2launchctl&lt;\/string&gt;<br \/>\n&lt;key&gt;RunAtLoad&lt;\/key&gt;<br \/>\n&lt;true\/&gt;<br \/>\n&lt;key&gt;UserName&lt;key&gt;<br \/>\n&lt;string&gt;pbw&lt;\/string&gt;<br \/>\n&lt;\/dict&gt;<br \/>\n&lt;\/plist&gt;<\/code><\/p>\n<div><i>Notes:<\/i><br \/>\nThe <i>UserName<\/i> field will, of course, be set to your own login name. \u00a0Likewise, the<i> pbw<\/i> prefix\u00a0 in the Label can be replaced with any suitable identifier, and the log file (see following) directed to a suitable location.<br \/>\nIf you need to debug the plist file, add the following lines.<\/div>\n<p><code>        &lt;key&gt;StandardOutPath&lt;\/key&gt;<br \/>\n&lt;string&gt;\/tmp\/plist.log&lt;\/string&gt;<br \/>\n&lt;key&gt;Debug&lt;\/key&gt;<br \/>\n&lt;true\/&gt;<\/code><\/p>\n<div>These lines are used in conjunction with the ECHO_TO_STDOUT variable in the executable file. If used, the <i>StandardOutPath<\/i> will point to a writable file on your system.<\/div>\n<div><i>Permissions &amp; Location:<\/i><\/div>\n<div>Again, give the file -rwxr-xr-x permissions. Place it in your <i>$HOME\/Library\/LaunchAgents<\/i> directory.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This method uses launchctl to manage environment variables for programs invoked directly from Finder. \u00a0See the launchctl man page, especially the section LEGACY SUBCOMMANDS. \u00a0It&#8217;s not entirely accurate, but that&#8217;s not unusual. \u00a0The critical subcommands are getenv, setenv, and unsetenv. The man page indicates that the export subcommand is available; it is not.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[19],"tags":[],"class_list":["post-34","post","type-post","status-publish","format-standard","hentry","category-code"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8SCfl-y","jetpack-related-posts":[{"id":39,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/setting-environment-variables-in-os-x-lion\/","url_meta":{"origin":34,"position":0},"title":"Setting Environment Variables in OS X Lion","author":"pbw","date":"Fri 3rd May '13","format":false,"excerpt":"If you want to set environment variables in OS X in such a way as to be recognised in applications run from Finder, it is not enough to set the env var in .profile. \u00a0You must also ensure that the variables are set in the file ~\/.MacOSX\/environment.plist. Setting values in\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":38,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/using-environment-plist-with-mountain-lion\/","url_meta":{"origin":34,"position":1},"title":"Using environment.plist with Mountain Lion","author":"pbw","date":"Sat 4th May '13","format":false,"excerpt":"UPDATE This post is now obsolete. For the preferred method in both Mountain Lion and Mavericks, see\u00a0 Setting environment variables in OS X Mountain Lion and Mavericks. With Mountain Lion (OS X 10.8), the environment settings from ~\/.MacOSX\/environment.plist are not taken into account when the background system environment is set\u2026","rel":"","context":"In &quot;Observations&quot;","block_context":{"text":"Observations","link":"https:\/\/pbw.id.au\/blog\/category\/personal\/observations\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":76,"url":"https:\/\/pbw.id.au\/blog\/2012\/01\/bultmann-the-problem-2-obsolete-mythology\/","url_meta":{"origin":34,"position":2},"title":"Bultmann: The Problem 2. Obsolete Mythology","author":"pbw","date":"Wed 25th Jan '12","format":false,"excerpt":"This is a follow-on from my\u00a0previous post. It looks at the subsection that follows from the summary view of the NT as mythology. I urge you to read this subsection in its entirety in\u00a0Kerygma and Myth. I will summarise it here, but it is such an unreasonable and unreasoning series\u2026","rel":"","context":"In &quot;Belief &amp; knowledge&quot;","block_context":{"text":"Belief &amp; knowledge","link":"https:\/\/pbw.id.au\/blog\/category\/belief\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":66,"url":"https:\/\/pbw.id.au\/blog\/2012\/03\/the-science-of-resurrection\/","url_meta":{"origin":34,"position":3},"title":"The Science of Resurrection","author":"pbw","date":"Fri 16th Mar '12","format":false,"excerpt":"In the collection of essays\u00a0on which I based my discussions of Bultmann, you will find, as the last essay, a summary of the original eight essays by Austin Farrer, entitled An English Appreciation. In the course of it, he offers this: The established, or virtually established, positions of science and\u2026","rel":"","context":"In &quot;Faith&quot;","block_context":{"text":"Faith","link":"https:\/\/pbw.id.au\/blog\/category\/belief\/faith\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":82,"url":"https:\/\/pbw.id.au\/blog\/2012\/01\/the-scale-of-god\/","url_meta":{"origin":34,"position":4},"title":"The Scale of God","author":"pbw","date":"Sat 7th Jan '12","format":false,"excerpt":"The cosmology of the ancient Hebrews has subject to a lot of snide comments by enlightened moderns, ever since those Copernicans appeared. Let's face it, it looks kind of quaint. The universe is viewed from the same platform that all but a tiny handful of us have always shared; the\u2026","rel":"","context":"In &quot;Belief &amp; knowledge&quot;","block_context":{"text":"Belief &amp; knowledge","link":"https:\/\/pbw.id.au\/blog\/category\/belief\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":749,"url":"https:\/\/pbw.id.au\/blog\/2019\/07\/israel-folau-and-the-rainbow-dhimmis\/","url_meta":{"origin":34,"position":5},"title":"Israel Folau and the Rainbow Dhimmis","author":"admin","date":"Fri 5th Jul '19","format":false,"excerpt":"[A version with slight differences was published 28th April, 2019 on Quadrant Online QED.] Notre Dame de Paris, on the \u00cele de Cit\u00e9, is a centrepiece of Europe\u2019s Christian cultural heritage; which is to say, a centrepiece of\u00a0our\u00a0heritage. The shocked and sombre reaction of\u00a0most\u00a0Parisians to the burning Cathedral was shared\u2026","rel":"","context":"In &quot;Faith&quot;","block_context":{"text":"Faith","link":"https:\/\/pbw.id.au\/blog\/category\/belief\/faith\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/34","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":29,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions"}],"predecessor-version":[{"id":1233,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/34\/revisions\/1233"}],"wp:attachment":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/media?parent=34"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/categories?post=34"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/tags?post=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}