This is a follow-up to #3600.
To make PowerShell fit into the world of POSIX-like shells on Unix platforms, so that it can be a viable alternative, it must:
The POSIX spec for the sh utility prescribes both.
Definitely not everything there is applicable to PowerShell, but I think it's important to at least fundamentally exhibit the same behavior and to document to what extent PowerShell is compliant.
A step has been made in the right direction by adding support for -i to start an interactive session - see #3558
More work is needed, _some of which would result in breaking changes_.
The list is not complete, but hopefully covers the most important aspects.
POSIX-like shells default to _not_ loading any initialization files _when commands are passed_ (whether via stdin or via -c), whereas PowerShell _always_ loads its profiles, the only exception being explicit suppression with -NoProfile.
-NoExit, the profiles should still be loaded by default (note that this ability to execute commands on startup _and_ keep the shell open for interactive use is unique to PowerShell: POSIX-like shells invariably _exit_ after executing commands).PowerShell already reads commands from stdin by default, and also when -Command - (which arguably should be -File -) is specified, but:
-s is the POSIX option for explicitly specifying standard input, and should be supported too.-s allows combining stdin command input with passing _parameters_, which PowerShell doesn't support; for instance, bash supports something like:echo 'echo "$# params"' | bash -s one two, which yields 2 params.-Command and -File issues:
They exhibit problematic interactive shell-like behaviors (with or without -NonInteractive) and lack consistent argument support - see #3223.
The way -Command currently parses the remaining arguments is problematic in itself and also fundamentally incompatible with POSIX-like shells - see https://github.com/PowerShell/PowerShell/issues/4024#issuecomment-311541803
[x] [Fixed by #4178] -File currently makes it impossible to pass Boolean values - see #4036.
[_This is already the case_] -c must be locked in as an alias for -Command, so that future additions of -c* parameters don't break -c due to ambiguity.
-i works now, but no error occurs when it is combined with -NonInteractive, even though they directly contradict each other.
-i (and therefore loading of the initialization files).-NonInteractive doesn't prevent an interactive session per se, only in-session interactive features such as Read-Host and confirmation prompts.[x] [Fixed by #9528] -l should be supported and trigger loading of the profiles - see #3600 for background.
-l is not part of POSIX, but supported by all major POSIX-like shells (bash, dash, ksh, and zsh)-l is for creating a _login_ shell - which some platforms use by default (macOS); on Unix, only special contexts such as ssh sessions use them routinely.[x] [Implemented with #4019] Passing a _positional argument_ should be interpreted as the _filename of a script to execute_ rather than a _shell command_.
In PowerShell terms: A positional argument should bind to -File, not -Command - this would be a breaking change, but would facilitate proper handling of shebang lines - see #3963
Conversely, to pass arbitrary shell commands, explicit use of -Command / -c should be required.
Current as of:
PowerShell Core 6.2.0
If there are conflicts with keys we could use a wrapper to start PowerShell Core.
Great feedback - thanks so much!
cc @JamesWTruher @BrucePay
Related discussion #992
@PowerShell/powershell-committee agrees that we should align with POSIX where it makes sense. It seems that many of the specific issues above have been addressed and we should evaluate each remaining ones separately without needing PS-Committee to review each one unless necessary
@SteveL-MSFT would it make sense to addressed the remaining open linked issues in version 7, when everybody expects a breaking change?
@mi-hol even though we are going with a major version update, it doesn't imply we are making lots of breaking changes. In fact, we are trying to minimize breaking changes since 6.0 shipped. We've had to make some targeted ones, but in general we are defaulting to not breaking unless necessary. From the list above, it seems the main contention is whether $profile gets loaded by default or not. Although this annoys me personally as I forget to add -NoProfile, it seems to big of a breaking change to accept.