Skip to content

Support -l for pwsh.exe #3600

Closed
Closed

Description

@vors

I hit a problem with vscode integrated terminal after changing my default shell to powershell on macOS.

microsoft/vscode#25035

I don't know how common is it to use -l as -noprofile in other shells, but if it's a fairly common interface we may want to support the same in ps.

Activity

  1. added
    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
    on Apr 19, 2017
  2. lzybkr commented on Apr 19, 2017

    @lzybkr
    Contributor

    It looks like sh, bash, fish, and zsh all support -l to mean it is a logon shell. ksh does not seem to support this parameter.

    That said, it looks like -l is roughly the opposite of -noprofile, see:

    https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell
    http://stackoverflow.com/questions/415403/whats-the-difference-between-bashrc-bash-profile-and-environment

    Note that because PowerShell doesn't use the environment for variables, non-login interactive shells need to run the profile whereas *nix shells mostly don't need to.

    Based on this - it feels like adding -l would make things more confusing.

  3. mklement0 commented on Apr 20, 2017

    @mklement0
    Contributor

    Just to add some more background (note that ksh does support -l, at least as of v93u+):

    If you pass a command (with -c) or script filename to a POSIX-like shell binary on startup, you get a non-interactive non-login shell in which no profile/initialization files are sourced by default - which is the opposite of PowerShell's default behavior.

    While the POSIX shell spec doesn't specify -l for sh, all major POSIX-compatible shells support it (dash, bash, ksh, zsh).

    Note that fish neither is nor aspires to be POSIX-compatible.

    -l indeed explicitly creates a login shell, which invariably sources the login profile(s) (e.g., ~/.bash_profile in Bash) - whether the shell is interactive or not.
    bash, ksh and zsh (but not dash) also support the more verbose alias --login.

    This is in contrast with the initialization file that is by default sourced for non-login shells - but only if they're interactive - such as ~/.bashrc.
    While not commonly used, you can force a shell to be interactive with option -i even when passing it a command / script filename.


    To contrast PowerShell's command-line behavior with that of POSIX-like shells:

    • PowerShell neither distinguishes between login and non-login shells, nor does it have distinct initialization files associated with that distinction (thankfully).

    • PowerShell always loads its profiles by default, and -noprofile must be used to suppress that.
      POSIX-like shells do not load any profiles/initialization files by default in non-interactive shells (when a command or script filename is passed, when a script is executed via its shebang line, when a non-interactive shell creates subshells or child shells).
      This discrepancy is problematic, I think.

      • POSIX-like shells started with -l / --login always source their *profile file(s), even for non-interactive shells.

      • Interactive POSIX-like shells not started with -l / --login source their *rc file(s). (zsh, as the (habitual) lone dissenter, also does so even with -l / --login); you can force creation of an interactive shell with -i.

    • PowerShell and POSIX-like shells alike automatically exit the session when a command / script filename is passed.

      • POSIX-like shells do so invariably; curiously, there is no (directly supported) way to execute commands on startup and then enter an interactive session.

      • PowerShell only exits by default and commendably allows the session to stay open via its -NoExit switch.

    • PowerShell's -Command / -File parameters roughly work like their POSIX counterparts (-c / by default), but there are problematic differences.

  4. lzybkr commented on Apr 20, 2017

    @lzybkr
    Contributor

    Sure enough, I didn't look closely enough at the error message I saw when running ksh -l under WSL - it was an error running /etc/profile.

    I do believe loading profiles for non-interactive sessions is a theoretical if not real problem. For example, my IT department forgets to use -noprofile all the time, meaning I can interfere with their scripts easily, on purpose or not.

  5. vors commented on Apr 22, 2017

    @vors
    CollaboratorAuthor

    Michael Klement (@mklement0) thank you for the detailed overview. Indeed, I was not aware of interactive vs login difference.

    Maybe we should rename the issue in something like "Should we change default loading profile behavior"?

  6. powercode commented on Apr 22, 2017

    @powercode
    Collaborator

    My €.02 is that the unix shells have a more sensible default, and we should take the opportunity now with the move to core to get things right.

  7. mklement0 commented on Apr 22, 2017

    @mklement0
    Contributor

    sergei (@vors) Happy to have this issue renamed/repurposed - my apologies for hijacking it somewhat: I hadn't fully read the initial problem, so just to address that:

    In the context of specifying a shell for VSCode, you do want the profile/initialization scripts to be sourced (using the example of bash):

    • On Linux, terminal programs create interactive non-login shells by default. Linux users keep their initialization commands in ~/.bashrc, because that file is the only (user-level) file that is sourced automatically when such a shell is created.

      • VSCode's default configuration emulates this behavior by passing no arguments to /bin/bash on Linux, which creates the same type of shell (interactive, non-login - when run in a terminal).
    • On macOS, by contrast, the default terminal program creates interactive login shells - that is, /bin/bash is always implicitly started with -l. The only (user-level) file that Bash login shells automatically source is ~/.bash_profile (not also ~/.bashrc). Therefore, some macOS users keep all their initialization commands in ~/.bash_profile only.

      • VSCode's default configuration emulates this behavior by passing -l to /bin/bash on macOS, which creates a logon shell.

    These platform differences are unfortunate, but they ultimately go back to the questionable behavior of not also loading ~/.bashrc in an interactive login shell.
    Arguably, the aspects of login and interactive should be separate: source ~/.bashrc whenever the shell is interactive (whether also a login shell or not), and source ~/.bash_profile whenever the shell is a login shell (whether also interactive or not).
    (Presumably, Bash was following historical practice there.)

    To compensate for this quirk, it is common practice to manually source ~/.bashrc from ~/.bash_profile (sometimes complemented with a check inside ~/.bashrc that aborts its loading if the shell is found to be non-interactive), by adding an explicit command to ~/.bash_profile.
    However, this is nothing more than a (inconsistently adhered-to) convention.

    Fortunately, PowerShell has no technical debt in that specific regard, but it is already at odds with respect to -NoProfile and -NonInteractive, both of which invert the logic of POSIX-like shells.

  8. mklement0 commented on May 9, 2017

    @mklement0
    Contributor

    I've created #3743 for a more comprehensive look at aligning the PowerShell CLI with that of POSIX-like shells.

  9. lypanov commented on Mar 5, 2018

    @lypanov

    It's a shame that at least -l can't be tackled. I've attempted to switch to using Powershell as my login shell but at least 2 tools I use on a daily basis expect -l to at least not reply with an "Invalid argument" error.

  10. changed the title [-]Consider supporting -l as an alias to -noprofile[/-] [+]Support `-l` for pwsh.exe[/+] on May 3, 2019
  11. SteveL-MSFT commented on May 3, 2019

    @SteveL-MSFT
    Member

    The whole login vs non-login shell semantics isn't something easily solved since we didn't take the breaking change with 6.0. However, it seems a workaround to enable users to use pwsh as their default (like in VSCode) would be to have -l as -LoadProfile which is effectively a no-op for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-FixedThe issue is fixed.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions