PowerShell
PowerShell copied to clipboard
Adding '.' to env:PATH adds/remembers the directory where the command was issued, does not denote the ambient current directory later on
Prerequisites
- [X] Write a descriptive title.
- [X] Make sure you are able to repro it on the latest released version
- [X] Search the existing issues.
- [X] Refer to the FAQ.
- [X] Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
When adding '.' to $env:PATH inside PowerShell (like suggested in #14106), the '.' seems to refer to the directory where the $env:PATH = $env:PATH + ';.' was issued, but does not denote the actual "current directory", when you change the current directory (using Set-Location).
(PS> $env:PATH="")
PS> mkdir $env:TEMP\a
PS> mkdir $env:TEMP\b
PS> echo "@echo from a" > $env:TEMP\a\t.cmd
PS> echo "@echo from b" > $env:TEMP\b\t.cmd
PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\b
PS> t.cmd
from a
That last line should output from b (also see "Expected haviour" below). Note that clearing env:PATH before all this is "optional" - the behavior is the same.
Interestingly, if you repeat $env:PATH=$env:PATH + ';.' in another directory (like above in $env:TEMP\b), then this new directory will be considered for the '.' (that is above invoking t.cmd would output from b, regardless of where the actual Get-Location is at).
Example:
PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\b
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from b
PS> cd $env:TEMP\a
PS> t.cmd
from b
Tests have been done with 7.1.3, but same behavior can be observed with 7.2.0-preview7.
Expected behavior
PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\a
PS> t.cmd
from b
Actual behavior
PS> cd $env:TEMP\a
PS> $env:PATH=$env:PATH + ';.'
PS> t.cmd
from a
PS> cd $env:TEMP\a
PS> t.cmd
from a
Error details
No response
Environment data
Name Value
---- -----
PSVersion 7.1.3
PSEdition Core
GitCommitId 7.1.3
OS Microsoft Windows 10.0.18363
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Visuals
No response
Hi, any news or opinions on this? I would have thought this to be a common issue with people migrating from typical CMD based envs, but then may not :-)
I vote to get this triaged also.
Adding '.' to the PATH list should always resolve to the current path when you change directories!
What is cmd.exe and bash behavior?
Bash and CMD.EXE treat it exactly like this. As possibly any other shell (csh ksh sh …). Which is why I opened this issue in the first place. I think even Windows powershell does it that way, but cannot verify right now.
It looks to me PowerShell command discovery somehow cached the t.cmd it found from the first time. From your example repro above, continue to run the following:
> cd c:\ # move to a completely unrelated location, which doesn't contain a 't.cmd' file
> t.cmd
from a
@daxian-dbw, it looks like it isn't the specific command whose location is cached, it is the entire $env:PATH value, with . getting resolved to the current directory at the time of caching.
Given PowerShell's - sensible - requirement to use .\ or ./ to invoke executables located in the current directory, I think it would make more sense to simply ignore attempts to add . to $env:PATH.
Arguably, even the current - obscure and probably accidental - behavior introduces a security vulnerability from that perspective.
@mklement0 I agree with your general sentiment about security. On some unix systems (or with some accounts) you also don't want to have the dot in your path and invoke all commands explicitly using ./command.
However, that should be the user's choice! Not the default forced upon by the shell.
(One could image a variable, say, $CurrentDirectoryWarningBehavior with a value of Enabled, that prints a warning every time PS uses the . to resolve a command from the path. - if that is possible at all, I don't know)
Because this issue is a regression to existing behavior and "prior work", confusing and annoying to users coming from or being experienced with:
- PowerShell (for Windows)
- a diversity of UNIX shells
- CMD.exe
@cklutz, you're right, I didn't realize it was a regression (I mistakenly thought it was broken in Windows PowerShell too).
By the way, on macOS a . entry is seemingly ignored altogether, whereas WSL with Ubuntu 20.04 seems to exhibit the same behavior as on Windows.
We're clearly dealing with a bug that needs to be resolved one way or the other.
I see your point about not forcing a choice upon the user, and personally I have no strong feelings about how this should be resolved.
To mention another possibility: emit a warning by default if . is found in $env:PATH on startup or whenever $env:PATH is modified in session with a value that has a . entry, and offer an opt-out preference variable.
P.S., @cklutz
As a workaround or possibly even something you may adopt as an alternative to trying to put . in $env:PATH you can rely on tab-completion to avoid having to type .\ or ./ every time.
This works as intended by default on Windows, but requires some tweaking on Unix-like platforms for a smooth experience (see this SO answer).
I gotta agree with @timkgithub and @cklutz. Let it do the obvious thing that everyone would expect. I hope this can be fixed the straightforward way.
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
Hello everyone, This is still very much a problem. A resolution would be rather welcome eventually. Let me ping the bot if I can. 🌴
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.
Please don't close issues that are real and affecting many.
The @WG group discussed this and agree that it's a bug. While there is a security aspect about this, it's still an explicit action that the user has taken. However, the real issue is that if you add "." to your path, the wrong location has been added to you path, once you change your location the previous location is remembered.
and $env:PATH may not represent the actual path (since . has been changed to /tmp but is not reflected.
This needs to stay open a bit longer; presumably until @JamesWTruher comes back to us with another update on this bug 🐞