Skip to content

Align PowerShell's CLI / startup behavior with POSIX-like shells such as Bash - command-line arguments #3743

@mklement0

Description

@mklement0

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:

    • -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:

  • [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.

    • 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 -NonInteractive doesn't prevent an interactive session per se, only in-session interactive features such as Read-Host and confirmation prompts.
  • [Fixed by Add support for -l to pwsh so that it is compatible with POSIX shell expectations #9528] -l should be supported and trigger loading of the profiles - see Support -l for pwsh.exe #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.
    • 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.

Current as of PowerShell 7.3.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Breaking-Changebreaking change that may affect usersCommittee-ReviewedPS-Committee has reviewed this and made a decisionIssue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifIssue-Metaan issue used to track multiple issuesResolution-No ActivityIssue has had no activity for 6 months or more

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions