-
Notifications
You must be signed in to change notification settings - Fork 8.1k
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