Skip to content

The pwsh CLI should support the -l / --login option for macOS compatibility, e.g. in VSCode #7704

Closed

Description

Related: #3743

On macOS, unlike on Linux, all (user-)default shell instances are started as login shells.

There are two mechanisms for invoking a shell as a login shell: (a) setting its argv[0] to contain - as the 1st character (that's what Terminal.app does) or (b) passing the -l (or --login) option to the shell executable.

If you make pwsh your default shell on macOS, certain applications may invoke pwsh with -l, which currently breaks the invocation.

Specifically, Visual Studio Code does that, so on a macOS system that uses /usr/bin/pwsh as the default shell, the integrated terminal fails to load (unless you happen to have the PowerShell extension installed and happen to open a *.ps1 file).

It would be sufficient for pwsh to accept -l / --login and otherwise simply ignore it, as the behavioral implications of this option in the context of bash don't apply to PowerShell.

Steps to reproduce

pwsh -l
pwsh --login

To see the problem in action with Visual Studio Code:

  • Add /usr/local/bin/pwsh to /etc/shells
  • Make PowerShell your default shell with chsh -s /usr/local/bin/pwsh
  • Open a new terminal and close existing Visual Studio Code windows.
  • Use code <file> to open a file for editing, where <file> must not be a PowerShell file.
  • Try to access the integrated terminal, which crashes due to invoking pwsh with -l.

Expected behavior

An interactive PowerShell session should start, as if the option hadn't been specified.

Actual behavior

Invalid argument '-l', did you mean:
...

The argument '--login' is not recognized as the name of a script file. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
...

Environment data

PowerShell Core v6.1.0-rc.1 on macOS 10.13.6
PowerShell Core v6.1.0-rc.1 on Ubuntu 16.04.4 LTS
PowerShell Core v6.1.0-rc.1 on Microsoft Windows 10 Pro (64-bit; Version 1803, OS Build: 17134.165)
Windows PowerShell v5.1.17134.165 on Microsoft Windows 10 Pro (64-bit; Version 1803, OS Build: 17134.165)

Activity

  1. changed the title [-]The pwsh CLI should support the -l option for macOS compatibility, e.g. in VSCode[/-] [+]The pwsh CLI should support the -l / --login option for macOS compatibility, e.g. in VSCode[/+] on Sep 4, 2018
  2. iSazonov commented on Sep 5, 2018

    @iSazonov
    Collaborator

    If we add the -l whether users expect that we fully support PowerShell Core as login shell?

  3. added
    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
    on Sep 5, 2018
  4. mklement0 commented on Sep 5, 2018

    @mklement0
    ContributorAuthor

    We would have to document that it is an effective no-op.

    De facto using pwsh as the default shell already works fine on macOS, after applying the workaround described in #6027 (comment)

    Eventually we'll need a documentation topic that describes all limitations with respect to using pwsh as the default shell on Unix-like platforms, currently summarized here: #975 (comment)

  5. iSazonov commented on Sep 5, 2018

    @iSazonov
    Collaborator

    Michael Klement (@mklement0) Could you please clarify about

    Technically, for PowerShell to detect being invoked as a login shell it must examine the equivalent of $0 (argv[0]) - the invocation name - to look for - as the 1st char.

    Is it pwsh -?
    Can this resolve the Issue too?

  6. mklement0 commented on Sep 5, 2018

    @mklement0
    ContributorAuthor

    Is it pwsh -?

    No, it is not an argument that reflects -, it is the name of the executable, reflected in argv[0] in C terms and in $0 in POSIX-like shell terms, which the caller sets to an arbitrary value - see below for details.

    Given that we're currently not modifying the behavior based on whether we're invoked as a logon shell or not, it's not even necessary to detect --prefixed invocations; of course we will have to, if we ever decide to change that (though it's not exactly clear what honoring login-shell status means, given that PowerShell cannot interpret /etc/profile directly).

    Can this resolve the Issue too?

    Not necessarily, because other tools - such as VSCode and at least hypothetically other terminal applications - may still use the -l option rather than the --prefix technique.

    That's why I think we should fix it in PowerShell rather than asking VSCode to modify its default-shell invocation.


    The --prefix convention

    By convention, shells should consider themselves login shells if the 1st character of $0 (argv[0]) is - (as an alternative to being passed the -l / --login option as an argument).

    The caller can "fake" the name/path of the executable it invokes as reported in $0, so even though it is pwsh that is invoked, $0 contains -pwsh when invoked from Terminal.app (and also from popular third-party alternative iTerm.app) while configured as the default shell.

    On Unix-like platforms, for instance, you can use Bash's exec builtin with the -a option to set $0, and the l option automatically prepends - to it.

    The tricky part is to get PowerShell to obtain this value, because [Environment]::GetCommandLineArgs() doesn't reflect it (it just contains the DLL path, e.g., /usr/local/microsoft/powershell/6-preview/pwsh.dll).

    The only way I personally know of to get this information from inside PowerShell (I haven't looked hard) would be to call the ps utility as follows, but that is obviously an undesirable cost to incur on startup:

    ps -o comm= $PID  # get true argv[0] / $0 value
  7. iSazonov commented on Sep 5, 2018

    @iSazonov
    Collaborator

    Seems we have already discussed that we could use different file names to address such scenarios (login shell, hide console windows, graphical shell and etc.). For the Issue we could create pwshl or pwsh_login runner.

  8. mklement0 commented on Sep 5, 2018

    @mklement0
    ContributorAuthor

    That would add unnecessary complexity:

    • It requires creating, maintaining, shipping, documenting a new executable, even though its sole purpose would be to ignore the -l / --login options.

    • User will need to know and remember that they must specify that a different executable when changing their default shell to PowerShell with chsh -s, which is far from obvious (adding the right executable to /etc/shells as a prerequisite should be done by the installer, which may already be happening).

  9. iSazonov commented on Sep 5, 2018

    @iSazonov
    Collaborator

    With -l option we only fix VS Code issue not Terminal.app
    I found the PowerShell Committee approvement #992 (comment)

  10. mklement0 commented on Sep 5, 2018

    @mklement0
    ContributorAuthor

    There is nothing to fix for Terminal.app or any other tools that use the --prefix convention, because PowerShell doesn't and need not care about what argv[0] truly contains - it simply has no impact.

    The approval you link to is in a way the opposite of what we're discussing here: a dedicated pwsh-np would suppress loading of profiles, whereas option -l in POSIX-like shells explicitly loads profiles (even in non-interactive shells) - and we definitely want to load $PROFILE if -l is passed.

  11. iSazonov commented on Sep 6, 2018

    @iSazonov
    Collaborator

    My idea was that we should use one approach if we want to follow the "standard"/bash/posix behavior.
    These settings are not for end users. Users should continue to use pwsh. System settings is for the installer or for the distributive creator - in this case, the end user does not need to know that another file is being launched.

  12. mklement0 commented on Sep 6, 2018

    @mklement0
    ContributorAuthor

    These settings are not for end users.
    in this case, the end user does not need to know that another file is being launched.

    That would be nice, but it's already not true for pwsh-np: As a script author, you must know to use it as the executable in the shebang line in order to get predictable behavior that doesn't load $PROFILE.

    Unfortunately, backward-compatibility concerns leave us no choice there, so a separate executable is required.

    Similarly, as stated, the end user would need to know that it's not pwsh, but pwshl (or whatever it would be) that must be passed to chsh -s in order to make PowerShell the default shell.

    Fortunately, in this case we do have the option to support that with the existing executable, by implementing -l / --login as no-op switches.

  13. iSazonov commented on Sep 7, 2018

    @iSazonov
    Collaborator

    Modern devices is locked - owners haven't root permissions. Corporate users too. Special devices (net devices, storage systems and so in) is locked too. Only a manufacturer configure the device. Or there is a config tools. Or installer. If user has a root permission one is high quality professional user. On windows systems we traditionally have GUI that helps eliminate errors in the configuration. In PowerShell we can add cmdlets to configure shells, schedule tasks and so on in right way.

    Posix discribes Bash behaviors. If somebody want to implement something Posix-compatible one have to implement or port new-Bash. For any other shell like PowerShell we are forced to seek a compromise and implement only what is possible.
    If the team published PowerShell specifications under Posix, we would be so Posix-compatible :-)
    I think real way is to develop and publish RFC to standardize PowerShell shell behavior. Then any manufacturer of distributions and systems can embed PowerShell in a standard and compatible manner. It may even be quite different than Posix/Bash.
    It should also be noted that in the 6.x version we must comply with backward compatibility, but we can do some useful workarounds (like you suggest). But this should be done so that in next 7.x version we could make more significant changes.

  14. mklement0 commented on Sep 7, 2018

    @mklement0
    ContributorAuthor

    Ilya (@iSazonov):

    Honestly, I have no idea what your first paragraph is talking about and how it relates to this discussion.

    As for the second paragraph:

    Posix describes Bash behaviors.

    As an aside: No, POSIX comprises a specification for a shell, whose executable is /bin/sh. Bash is a POSIX-like shell, but even when you run it in POSIX compatibility mode it isn't fully POSIX-compliant.

    For any other shell like PowerShell we are forced to seek a compromise

    And implementing -l / --login as quiet no-op options is exactly such a compromise.

    No one is looking for 100% POSIX compatibility, which fundamentally cannot be achieved by PowerShell.

    What matters is that in practice you can use it as your default shell on all of the supported platforms, and the proposed change is a step in that direction.

    If someone wants to take on the work of formalizing the extent to which PowerShell is POSIX-compatible, that's great, but doing so is not a prerequisite for the change proposed here.

  15. iSazonov commented on Sep 7, 2018

    @iSazonov
    Collaborator

    Michael Klement (@mklement0) Thanks for great discussion!

    Yes, adding '-l' we resolve the Issue with VS Code.
    My main fear was and is that with getting '-l' users will expect that we implementfully fully functional login shell. So first of all we need to create RFC and describe all shell modes. This will allow Community to use PowerShell in the standard way.

    It is a question for PowerShell Committee.

  16. SteveL-MSFT commented on Sep 19, 2018

    @SteveL-MSFT
    Member

    @PowerShell/powershell-committee would accept adding -l that output a warning message akin to: "The -l switch was used to indicate starting a login shell, however, PowerShell Core 6 does not currently support this meaning that certain environment variables will not be available or complete.". This would allow tools that expect -l to be there to work and pwsh to startup and allows us to support the complete work of a login shell in the future.

  17. added
    Committee-ReviewedPS-Committee has reviewed this and made a decision
    and removed
    Review - CommitteeThe PR/Issue needs a review from the PowerShell Committee
    on Sep 19, 2018
  18. mklement0 commented on May 9, 2019

    @mklement0
    ContributorAuthor

    Resolved in #9528, which adds a -l / -LoadProfile switch that is a no-op for now.

    See also: the RFC to make -l functional: https://github.com/PowerShell/PowerShell-RFC/pull/171/files

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

    Committee-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 reclassifResolution-FixedThe issue is fixed.WG-Interactive-Consolethe console experience

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions