Repository navigation
Align PowerShell's CLI / startup behavior with POSIX-like shells such as Bash - command-line arguments #3743
Description
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:
- support certain command-line parameters (options)
- exhibit certain default behaviors on startup
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.- The POSIX behavior is the more sensible default: it makes for a more predictable execution environment and doesn't incur the cost of sourcing the initialization files.
- Aligning PowerShell with this behavior would be a breaking change.
- Arguably, when commands are combined with
-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). - See #!/usr/local/bin/powershell bang should not load profile #992, which has a green-lit, but never-implemented committee decision to implement a separate CLI entry point that doesn't load profiles,
pwsh-np
-
PowerShell already reads commands from stdin by default, and also when
-Command -(which arguably should be-File -) is specified, but:-sis the POSIX option for explicitly specifying standard input, and should be supported too.-sallows combining stdin command input with passing parameters, which PowerShell doesn't support; for instance,bashsupports something like:
echo 'echo "$# params"' | bash -s one two, which yields2 params.
-
-Commandand-Fileissues:-
They exhibit problematic interactive shell-like behaviors (with or without
-NonInteractive) and lack consistent argument support - see CLI:pwsh -Command -andpwsh -File -unexpectedly exhibit pseudo-interactive behavior, lack support for argument passing #3223. -
The way
-Commandcurrently parses the remaining arguments is problematic in itself and also fundamentally incompatible with POSIX-like shells - see Command line arguments with a dollar sign #4024 (comment) -
[Fixed by Allow passing $true/$false as parameter to script using -File #4178]
-Filecurrently makes it impossible to pass Boolean values - see Executing powershell script with bool parameter doesnt work #4036.
-
-
[This is already the case]
-cmust be locked in as an alias for-Command, so that future additions of -c* parameters don't break-cdue to ambiguity. -
-iworks now, but no error occurs when it is combined with-NonInteractive, even though they directly contradict each other.- Note that starting a POSIX-like shell without operands in a terminal (with stdin and stderr connected to a terminal) implies
-i(and therefore loading of the initialization files). - Note that
-NonInteractivedoesn't prevent an interactive session per se, only in-session interactive features such asRead-Hostand confirmation prompts.
- Note that starting a POSIX-like shell without operands in a terminal (with stdin and stderr connected to a terminal) implies
-
[Fixed by Add support for
-lto pwsh so that it is compatible with POSIX shell expectations #9528]-lshould be supported and trigger loading of the profiles - see Support-lfor pwsh.exe #3600 for background.-lis not part of POSIX, but supported by all major POSIX-like shells (bash,dash,ksh, andzsh)-lis for creating a login shell - which some platforms use by default (macOS); on Unix, only special contexts such assshsessions use them routinely.- Login shells load a separate set of initialization files compared to interactive non-login shells, but PowerShell has no distinction between login and non-login shells.
- See https://github.com/PowerShell/PowerShell-RFC/pull/171/files for proposed changes to make PowerShell behave more like POSIX-like login shells.
-
[Implemented with Change positional parameter for powershell.exe from -Command to -File #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 shebang without .ps1 extension ends up in recursive loop calling powershell #3963 -
Conversely, to pass arbitrary shell commands, explicit use of
-Command/-cshould be required.
-
Current as of PowerShell 7.3.1
Activity
iSazonov commentedon May 9, 2017
If there are conflicts with keys we could use a wrapper to start PowerShell Core.
jpsnover commentedon May 12, 2017
Great feedback - thanks so much!
7 remaining items
SteveL-MSFT commentedon Jan 3, 2018
@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
mi-hol commentedon Oct 30, 2019
Steve Lee (@SteveL-MSFT) would it make sense to addressed the remaining open linked issues in version 7, when everybody expects a breaking change?
SteveL-MSFT commentedon Oct 31, 2019
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.microsoft-github-policy-service commentedon Nov 16, 2023
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.
microsoft-github-policy-service commentedon Nov 16, 2023
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.
microsoft-github-policy-service commentedon Nov 16, 2023
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.
microsoft-github-policy-service commentedon Nov 23, 2023
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.