OS X changes the PATH before executing a zsh script, even in non-interactive mode

Originator:mdeaudelin
Number:rdar://20991428 Date Originated:2015/05/17
Status:Open Resolved:
Product:OS X Product Version:OS X 10.10.3 (14D136)
Classification: Reproducible:Always
 
Summary:
The /etc/zshenv initialization file for the zsh shell resets the PATH environment variable by calling /usr/libexec/path_helper. Since zshenv is executed every time a zsh script is executed (even in non-interactive non-login mode), the PATH environment variable of the script may differ from the one of its parent process for no good reason.

This behavior is incorrect. path_helper should be called either in /etc/zprofile (login shells only) or /etc/zshrc (login/interactive shells only). This is important so that bash and zsh exhibit similar behavior (for bash, path_helper is only called from /etc/profile, which is only executed if bash is running as a login shell).

Steps to Reproduce:
Assuming an environment with a MacPorts install, and a newer version of vim installed through it. The problem is not MacPorts-specific though, but is easier to demonstrate this way. 

1. Create a basic zsh script, like so, and make it executable:
#!/bin/zsh
echo "zsh script path is: $PATH"
echo "zsh will find vim in: $(which vim)"

2. Open a terminal window (you can use whatever shell you'd like).
3. Add the MacPorts directories to the front of your PATH.
(export PATH="/opt/local/bin:/opt/local/sbin:$PATH")
4. Execute the script.

5. Create a similar script using bash, and make it executable:
#!/bin/bash
echo "bash script path is: $PATH"
echo "bash will find vim in: $(which vim)"

6. Repeat steps 2 and 3, then execute the script from step 5.

Expected Results:
The script should print the PATH it inherited from its parent. Since that path contains the MacPorts directories at the beginning, they will be searched first, and "which vim" will return the MacPorts copy, like so:

zsh script path is: /opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin...
zsh will find vim in: /opt/local/bin/vim

bash script path is: /opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin...
bash will find vim in: /opt/local/bin/vim

Actual Results:
The PATH variable is reset and not inherited from the parent process. The results from the zsh script and the bash script differ.

zsh script path is: /usr/local/bin:/usr/bin:/bin:/usr/sbin...
zsh will find vim in: /usr/bin/vim

bash script path is: /opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin...
bash will find vim in: /opt/local/bin/vim

Version:
Reproduced on OS X 10.10.3 (14D136)
Affects at least versions 10.8 and newer.

Notes:

Configuration:

Attachments:

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!