Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zsh: fix performance issues related to PATH #5268

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

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.

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