hschmidt / EnvPane

EnvPane - An OS X preference pane for environment variables
Other
734 stars 52 forks source link

EnvPane is not setting environment variable PATH #5

Open uweguenther opened 11 years ago

uweguenther commented 11 years ago

If I put the following in /etc/launchd.conf:

setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

As a consequence of that PATH for Applications gets modified from:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

to

/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

If I comment the line from above in /etc/launchd.conf, reboot and use EnvPane to set the PATH, the PATH does not get prefixed with /opt/local/bin:/opt/local/sbin: in normal applications. As far as I can see EnvPane is creating:

~/.MacOSX/environment.plist

in my $HOME with the following content:

<?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>PATH</key>
    <string>/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
</dict>
</plist>

But it looks like OS X does not use the content of ~/.MacOSX/environment.plist. Is there something wrong with your agent?

How do I test? I wrote a small Java program dumping put the PATH as follows:

public class Main {
    public static void main (String[] args) {
        System.out.println("PATH=" + System.getenv().get("PATH"));
    }
}

My expectation of EnvPane is to get the environment variable in my application exact the same way as I defined it in EnvPane itself, without rebooting my box, Please correct my if I am wrong.

I found the following output in my logfiles while filtering for net.hannesschmidt:

3/24/13 9:48:08.410 AM EnvAgent[5645]: Started agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (5645)
3/24/13 9:48:08.413 AM EnvAgent[5645]: Exiting agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (5645)
3/24/13 9:52:35.191 AM EnvAgent[178]: Started agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (178)
3/24/13 9:52:35.281 AM EnvAgent[178]: Exiting agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (178)
3/24/13 9:53:25.570 AM EnvAgent[577]: Started agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (577)
3/24/13 9:53:25.573 AM EnvAgent[577]: Exiting agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (577)
3/24/13 9:54:27.833 AM EnvAgent[718]: Started agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (718)
3/24/13 9:54:27.837 AM EnvAgent[718]: Exiting agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (718)
3/24/13 9:54:27.932 AM com.apple.launchd.peruser.501[137]: (net.hannesschmidt.EnvAgent) Throttling respawn: Will start in 10 seconds
3/24/13 9:54:37.943 AM EnvAgent[736]: Started agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (736)
3/24/13 9:54:37.946 AM EnvAgent[736]: Exiting agent /Users/uwe/Library/Application Support/net.hannesschmidt.EnvAgent/EnvAgent (736)

Just tell me if you need more details or some other information. I am running 10.8.3 at the moment.

hschmidt commented 11 years ago

Thank you for your detailed issue report, Uwe.

PATH is special because the system has to take security constraints into account. I might not be able to work around those constraints in EnvPane.

It seems that PATH is not controlled by the user-specific launchd instance (the one my agent talks to), but rather by root's launchd instance, i.e. the one with PID 1. I could make the agent talk to the root instance but that would require asking the user (assuming they're an admin) for their password. It would have the same effect as setting PATH in /etc/launchd.conf, making it largely redundant. Additionally, it would be effective for all users rather than just the current one. This is why I tend to close this issue as "won't fix". Alternatively, I could add special code for PATH that causes it to be written to /etc/launchd.conf rather than ~/.MacOSX/environment.plist. At the very least I should include this oddity in EnvPane's documentation. I might also display a warning if a user sets PATH using EnvPane. I am not sure yet. What are your thoughts on this?

Please note that there are more subtleties involving PATH with respect to shell sessions, e.g. Terminal.app. Here PATH is controlled largely by path_helper(8) which reorders the entries in PATH to the effect that custom entries appear at the end. You can verify this by running printenv PATH in Terminal and you will see that your PATH will look more like

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/local/bin:/opt/local/sbin

You say that your Java test app prints the PATH with the custom entries prepended. To me this indicates that you are not starting it from a shell, otherwise the custom entries would appear at the end. Am I correct?

Nevertheless, I am still confounded by the log snippet you posted. It should contain a line generated by the agent that says

3/24/13 6:08:20.780 PM EnvAgent[17045]: Setting 'PATH' to '/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'

Could you make sure you tested the latest version of EnvPane (v0.3)?

To summarize and to aid in your diagnostics,

launchctl getenv PATH 

prints the current user's launchd environment, the one that affects that user's GUI apps.

sudo launchctl getenv PATH

prints the global launchd instance's environment. Its PATH overrides the user-specific one. The overriding seems to happen at login time.

printenv PATH 

prints the shell's environment, which is further scrambled by path_helper(8).

uweguenther commented 11 years ago

I have been stumbled already about /usr/libexec/path_helper -s triggered by /etc/profile. The work arround for me was to setup /etc/paths the same way I setup /etc/launchd.conf regards to path order:

/opt/local/bin
/opt/local/sbin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin

Before I filed the bug report - I downloaded the latest EnvPane v0.3, because it was already banned from Mac. So it should be the latest one.

I get the following output with an empty /etc/launchd.conf, but a PATH set via EnvPane to /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:

uweguenther commented 11 years ago

What are your thoughts on this?

If I just step back and lock at the issue from a users point of view, it seems to me setting the PATH is a killer feature for your app. Most of the time I find my self messing around with the PATH. Especially if you do Java development, where each program like Tomcat, Ant, Maven or you name it is self contained and you have to hook it up with your PATH. But this is just my view to the world. I know there is still the path_helper issue if you traveling around in the wonderful world of shell.

I totally understand you to not end up in maintenance nightmare here, because of all the mess Apple created here.

Ok, this is how I would do it:

A completely different solution would be to to deal with 2 sets of environments global and local. This is a bit how it's done in MS Windows since NT 4.0. This would mean your UI is some how split in user vars and global vars. If a user is admin you can make the global vars editable (with a lock symbol, like ist usually done in pref dialogs). At the end global vars would end up in etc/launchd.conf and local vars would end up in ~/.MacOSX/environment.plist.

This approach would delegate the whole PATH issue to the user.

lenix commented 11 years ago

I really like the second approach of having two different scopes. I stumbled upon EnvPane while looking for a graphical solution to modify PATH, i don't care too much about other environment variables.