romkatv / zsh4humans

A turnkey configuration for Zsh

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

  1. The Homebrew versions of Gnu tools are given highest preference
  2. The system paths follow next (which is where I can see zsh4humans adding $HOMEBREW_PREFIX/bin )
  3. Next should be $HOMEBREW_PREFIX/bin
  4. 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!!