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

Unix utilities expect $env:PWD to reflect the current directory, as per POSIX #7388

Closed
mklement0 opened this issue Jul 27, 2018 · 8 comments
Closed
Labels
Issue-Enhancement the issue is more of a feature request than a bug Resolution-No Activity Issue has had no activity for 6 months or more WG-Engine core PowerShell engine, interpreter, and runtime

Comments

@mklement0
Copy link
Contributor

POSIX mandates the presence of an environment variable named PWD that should "represent an absolute pathname of the current working directory."

That is, POSIX-like shells keep the value of this env. variable in sync with their working dir. so that (non-shell) processes created from the shell can rely on it reflecting the shell's notion of the current dir.

PowerShell currently doesn't set this environment variable (it only sets its internal automatic $PWD variable, which other processes cannot see), which can have unintended consequences when invoking Unix utilities that rely on it.

This problem is conceptually related to #3428, for which there is no good solution due to its in-process nature.

In the case at hand, however, since a child process must be created to invoke an external program, it should be possible to add a PWD environment variable reflecting PowerShell's current filesystem location to the environment block of the new process.

Steps to reproduce (on macOS or Linux)

# Switch to an arbitrary location and make the Perl process display the value of $env:PWD
Set-Location /tmp; perl -le 'print $ENV{PWD}'  

Expected behavior

/tmp

That is, the external utility's process should see PowerShell's current filesystem location in its PWD environment variable.

(Note that using another shell (e.g., bash) for this test wouldn't be a valid test, because POSIX-like shells set the PWD environment variable themselves.)

Actual behavior

/home/jdoe     # e.g.

Even with PowerShell configured as the user's default shell, $env:PWD is still set at the time the PowerShell session starts, and seemingly always reflects the user's home dir.

Environment data

PowerShell Core v6.1.0-preview.4 on macOS 10.13.6
PowerShell Core v6.1.0-preview.4 on Ubuntu 16.04.4 LTS
@thezim
Copy link
Contributor

thezim commented Jul 27, 2018

Is there a goal to make PowerShell POSIX compliant?

@mklement0
Copy link
Contributor Author

@thezim:

It's not about POSIX compliance per se - it's just that POSIX-decreed functionality is, by and large, the common denominator across macOS and Linux - see #6518 (comment)

If PowerShell wants to be a good cross-platform citizen and aspires to be the "universal shell" (which I hope it does), it must not contravene fundamental expectations of any platform's native utilities.

Utilities (command-line programs) on Unix-like platforms may rely on environment variable ENV ($env:PWD, in PowerShell terms) reflecting the notion of the calling shell's current directory.

PowerShell not respecting that can lead to subtle failures.

If you want a specific example:

After switching my default shell to PowerShell on macOS, my (standardized across projects) Makefiles started to break, because they try to add project-relative directories to $env:PATH, based on $env:PWD.

@iSazonov iSazonov added Issue-Enhancement the issue is more of a feature request than a bug WG-Engine core PowerShell engine, interpreter, and runtime labels Jul 30, 2018
@iSazonov
Copy link
Collaborator

I believe it will be easy-to-fix and good enhancement.

lucyllewy pushed a commit to lucyllewy/PowerShell that referenced this issue Feb 15, 2019
Set the UNIX Environment variable $env:PWD to the full filesystem path
for the current working directory upon Set-Location. This also copes
when the current location is set to a PSDrive. In such circumstances the
environment variable is expanded to the full FileSystem provider path.

Fixes PowerShell#7388

Signed-off-by: Daniel Llewellyn <daniel@bowlhat.net>
lucyllewy pushed a commit to lucyllewy/PowerShell that referenced this issue Feb 18, 2019
Set the UNIX Environment variable $env:PWD to the full filesystem path
for the current working directory upon Set-Location. This also copes
when the current location is set to a PSDrive. In such circumstances the
environment variable is expanded to the full FileSystem provider path.

Fixes PowerShell#7388

Signed-off-by: Daniel Llewellyn <daniel@bowlhat.net>
@Happycoil
Copy link

Happycoil commented Aug 21, 2019

Just got bitten by this after changing my login shell to pwsh 7.0.0-preview.3. I expect lots of tools have code like this: https://github.com/chef/chef/blob/39cf0beb9ccc0fa0f60fa9d52b3c0a2bccc6c0f1/chef-config/lib/chef-config/workstation_config_loader.rb#L141-L149 and more people will be using pwsh as their login shell now...

My particular issue can be solved by setting $env:PWD to an empty string, but I expect that'll break something else I haven't tried yet.

GitHub
A systems integration framework, built to bring the benefits of configuration management to your entire infrastructure. - chef/chef

@iSazonov
Copy link
Collaborator

Code references:

private Process Start(ProcessStartInfo startInfo)
{
Process process = null;
if (startInfo.UseShellExecute)
{
process = StartWithShellExecute(startInfo);
}
else
{
#if UNIX
process = new Process() { StartInfo = startInfo };
SetupInputOutputRedirection(process);
process.Start();
if (process.StartInfo.RedirectStandardOutput)
{
process.BeginOutputReadLine();
}
if (process.StartInfo.RedirectStandardError)
{
process.BeginErrorReadLine();
}
if (process.StartInfo.RedirectStandardInput)
{
WriteToStandardInput(process);
}
#else
process = StartWithCreateProcess(startInfo);
#endif
}
return process;

_nativeProcess = new Process() { StartInfo = startInfo };
_nativeProcess.Start();

@SteveL-MSFT SteveL-MSFT added this to the vNext-Consider milestone Oct 18, 2019
@SteveL-MSFT SteveL-MSFT added this to To do in Shell via automation Oct 18, 2019
@TravisEz13 TravisEz13 modified the milestones: 7.1-Consider, 7.2-Consider Aug 20, 2020
@rjmholt
Copy link
Collaborator

rjmholt commented Aug 20, 2020

It seems we could implement this with something like this property

Copy link
Contributor

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

@microsoft-github-policy-service microsoft-github-policy-service bot removed this from the 7.3-Consider milestone Nov 23, 2023
Shell automation moved this from To do to Done Nov 23, 2023
@carschandler
Copy link

carschandler commented Mar 7, 2024

Please re-open this. I believe the benefits far outweigh any cons, if there even are any. For example, I'm using a project with a Taskfile defined that assumes the PWD environment variable is set, which works for all platforms except Windows! Someone else already mentioned the same thing for Makefile. I'd imagine there are tons of build systems that have the same issue. We already have the automatic $PWD variable, so why not just expand this into a true environment variable? Just to explicitly not be POSIX compliant?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement the issue is more of a feature request than a bug Resolution-No Activity Issue has had no activity for 6 months or more WG-Engine core PowerShell engine, interpreter, and runtime
Projects
Linux/Mac Usability
  
Awaiting triage
Shell
  
Done
Development

Successfully merging a pull request may close this issue.

8 participants