Skip to content

Comments

zsh: fix performance issues related to PATH#5268

Open
samhocevar wants to merge 1 commit intomsys2:masterfrom
samhocevar-forks:fix-zsh-path-performance
Open

zsh: fix performance issues related to PATH#5268
samhocevar wants to merge 1 commit intomsys2:masterfrom
samhocevar-forks:fix-zsh-path-performance

Conversation

@samhocevar
Copy link
Contributor

When $PATH contains / and command foo is run, zsh will try to execute //foo instead of /foo, which will attempt to contact a network share on server foo, causing DNS and CIFS requests that will greatly slow down the shell. And if /foo actually exists, it will not be found.

As a workaround, we do not insert the additional '/' if the path element already ends with a slash.

Another workaround for the users would be to put /. instead of / in $PATH.

When $PATH contains "/" and command "foo" is run, zsh will try to execute "//foo"
instead of "/foo", which will attempt to contact a network share on server "foo",
causing DNS and CIFS requests that will greatly slow down the shell. And if "/foo"
actually exists, it will not be found.

As a workaround, we do not insert the additional '/' if the path element already
ends with a slash.

Another workaround for the users would be to put "/." instead of "/" in $PATH.
@samhocevar
Copy link
Contributor Author

A very easy repro example (using $RANDOM to bypass hashing):

% for d in / /.; do echo PATH=$d; for _ in 1 2 3; do time PATH=$d unknowncommand$RANDOM 2>/dev/null; done; done
PATH=/
PATH=$d unknowncommand$RANDOM 2> /dev/null  0.01s user 0.00s system 1% cpu 1.303 total
PATH=$d unknowncommand$RANDOM 2> /dev/null  0.03s user 0.00s system 2% cpu 1.306 total
PATH=$d unknowncommand$RANDOM 2> /dev/null  0.01s user 0.01s system 2% cpu 1.310 total
PATH=/.
PATH=$d unknowncommand$RANDOM 2> /dev/null  0.00s user 0.00s system 0% cpu 0.010 total
PATH=$d unknowncommand$RANDOM 2> /dev/null  0.00s user 0.00s system 0% cpu 0.010 total
PATH=$d unknowncommand$RANDOM 2> /dev/null  0.00s user 0.00s system 0% cpu 0.010 total
%

@Biswa96
Copy link
Member

Biswa96 commented Mar 19, 2025

Should it be reported to upstream zsh project?

@samhocevar
Copy link
Contributor Author

I don’t really know. Do they care about the Cygwin emulation layer? Because it’s Cygwin that causes //foo to not be the same as /foo like on most Unix systems, so they aren’t wrong in making the assumption.

@lazka
Copy link
Member

lazka commented Mar 20, 2025

Just wondering, why do you have "/" in PATH?

I haven't tested it but "///" might also work as a workaround, as that is equal to / according to POSIX, while "//" isn't.

@lazka
Copy link
Member

lazka commented Apr 1, 2025

Since this is an uncommon use case, has a workaround, and should ideally be reported upstream since double slashes should also not be used on other systems, I tend towards closing this.

@samhocevar
Copy link
Contributor Author

I have / in PATH because:

  • my Windows system has C:\tools\msys64\ in %PATH%
  • I use MSYS2_PATH_TYPE=inherit
  • MSYS2 simplifies C:\tools\msys64\ to / when building the Unix-style $PATH

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants