Question about path ordering
arrrgi opened this issue · comments
I recently configured zsh4humans with Homebrew on Linux but quickly ran into some issues with Homebrew's version of OpenSSL being preferred over the system installed OpenSSL (I'm behind a corp firewall and I have to import a self-signed CA certificate)
When I check the path environment variable, I noticed that the Homebrew directories came first before my standard system path entries, resulting in the Homebrew OpenSSL being used. I only found this out as I had imported the Root CA to the standard location but tools like curl, etc were failing to find it.
My path config in $ZDOTDIR/.zshrc looks like:
path=(
"${HOMEBREW_PREFIX}/opt/coreutils/libexec/gnubin"
"${HOMEBREW_PREFIX}/opt/gnu-sed/libexec/gnubin"
"${HOMEBREW_PREFIX}/opt/gnu-tar/libexec/gnubin"
"${HOMEBREW_PREFIX}/opt/grep/libexec/gnubin"
$path
)
path+=(
"${HOMEBREW_PREFIX}/bin"
"${HOME}/.local/bin"
)
with the logic of this being:
- The Homebrew versions of Gnu tools are given highest preference
- The system paths follow next (which is where I can see zsh4humans adding
$HOMEBREW_PREFIX/bin
) - Next should be
$HOMEBREW_PREFIX/bin
- Finally any bare binaries in
~/.local/bin
Can you think of any way I can optimise the path arrays to match the order stated?
My current workaround was to append my corporate Root CA to the $HOMEBREW_PREFIX/etc/ssl/ca-certificates/cert.pm but I can't guarantee this is stable, so the local system version of OpenSSL is preferred.
Output of echo $PATH
:
$ echo $PATH
/Users/rgillson/.local/share/.volta/bin:/opt/homebrew/opt/coreutils/libexec/gnubin:/opt/homebrew/opt/gnu-sed/libexec/gnubin:/opt/homebrew/opt/gnu-tar/libexec/gnubin:/opt/homebrew/opt/grep/libexec/gnubin:/Users/rgillso
n/.cache/zsh4humans/v5/zsh4humans/zb:/opt/homebrew/bin:/Users/rgillson/.local/bin:/Users/rgillson/.cargo/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/var/run/com.apple.security.cryptexd/codex.s
ystem/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Applications/VMware Fusion Tech Prev
iew.app/Contents/Public:/usr/bin:/bin:/usr/sbin:/sbin:/Users/rgillson/.cache/zsh4humans/v5/fzf/bin:/Users/rgillson/.orbstack/bin
Here are a few tools you can use:
# Remove all subdirectories of /foo/bar from path.
path=(${path:#/foo/bar/*})
# Remove ~/.local/bin from path.
# Note that you have to use $HOME instead of ~ if the tilde
# isn't the first character of the pattern.
path=(${path:#~/.local/bin})
# Remove a bunch of directories from path and then append them.
() {
path=(${path:|argv} $@)
} /foo/bar /baz/qux
If I understand your requirements correctly, this should work:
path=(
# The Homebrew versions of Gnu tools.
$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin
$HOMEBREW_PREFIX/opt/gnu-sed/libexec/gnubin
$HOMEBREW_PREFIX/opt/gnu-tar/libexec/gnubin
$HOMEBREW_PREFIX/opt/grep/libexec/gnubin
# The default directories minus ~/.local/bin and $HOMEBREW_PREFIX/*.
${path:#($HOME/.local/bin|$HOMEBREW_PREFIX/*)}
# Extra directories at the end.
$HOMEBREW_PREFIX/bin
~/.local/bin
)
If this does not do exactly what you want, I'm sure you'll figure out how to tweak it.
A more principled solution would be to uninstall the brew binaries that don't work.
Thanks, plenty enough for me to figure it out.
A more principled solution would be to uninstall the brew binaries that don't work.
Would agree normally but in this case I'm confident the bundled Homebrew OpenSSL version is part of a few other apps dependencies (and a slightly newer version than the Debian/Ubuntu packaged version)
Awesome tips, definitely one for the record as these make more sense to me than what's in the Zsh docs. Thanks again!!