0

I'm trying to source a file from a launch agent, but it's unclear how to accomplish that (or if it's even possible). I know it's easy to setenv for single variables, but I need to bring in a bunch of them, so source is what I need.

<?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>my.sourcerer</string>
    <key>ProgramArguments</key>
    <array>
        <string>source</string>
        <string>my_file.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>/path/to/source</string>
</dict>
</plist>

This loads and starts without any issue it seems:

$ launchctl load ~/Library/LaunchAgents/my.sourcerer.plist
$ launchctl start ~/Library/LaunchAgents/my.sourcerer.plist

But when I printenv none of my sourced environment variables show up. If manually I do:

$ source /path/to/source/my_file.sh
$ printenv

Then all of the variables show up. Why doesn't the launchctl agent seem to load the variables into my environment?

ctfd
  • 338
  • 3
  • 14
  • Possible duplicate of [Environment variables in Mac OS X](https://stackoverflow.com/questions/603785/environment-variables-in-mac-os-x) –  Mar 22 '19 at 23:58
  • 1
    What `source` does is run commands from a file *in the current shell*, and that doesn't make sense except in a shell; launchd isn't a shell, so it doesn't make sense there. But even if you could, I don't think it would do what you want. Each process has its own environment variables (though child processes start with a copy of their parent's environment), so if you could use `source` there it would set the variables *for the launchd process*, not for your shell processes. – Gordon Davisson Mar 23 '19 at 00:42
  • Launchd runs programs. The `source` command is a shell builtin. It is not a program. If you look at */var/log/system.log* you should see error messages related to launching your `my.sourcerer.plist` config. Furthermore, you can't modify the environment of your current shell (or any other already running process) setting an env var in a process created by launchd. What is it you're really trying to do? – Kurtis Rader Mar 23 '19 at 01:35
  • @GordonDavisson: That makes sense, but then why then would I have some apps that `setenv` from a launch agent? Or rather, why would it be useful rather than setting it in `~/.bash_profile`? – ctfd Mar 23 '19 at 03:35
  • @KurtisRader: I have an app (not one I created) that requires it to use `source initialize` to setup environment variables before it runs. I was hoping that I could streamline the process by having the environment variables automatically set at boot so that process was not necessary. – ctfd Mar 23 '19 at 03:39

1 Answers1

1

Based on the comments to the question I'm going to go out on a limb and try to answer the question.

It seems you want to launch a program when you login rather than manually after you open your first terminal session. The solution is to create a script that includes the necessary source command to initialize the environment. Then make that script pathname the first arg of your ~/Library/LaunchAgents/my.sourcerer.plist config.

You could also statically set those vars via launchctl setenv. But I would not recommend that approach because it obviously isn't dynamic. That is, if the output of the sourced script ever changes the statically set env vars inherited by every process would not change.jj

Kurtis Rader
  • 6,734
  • 13
  • 20
  • How would I be able to confirm that the environment variables that I source in the script are set when I login? – ctfd Mar 24 '19 at 06:14
  • When I wrote "login" above I meant logging in to the desktop environment after booting the computer. And I assumed you would launch the program that needs the env vars from the same script you had launchd run. If you want to be able to run that program from an interactive shell you'll need to put the `source` command in the appropriate shell config file; e.g., *~/.bashrc*. I get the distinct sense you're trying to make a simple problem more complicated than it needs to be. – Kurtis Rader Mar 24 '19 at 23:13