You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Just to add some more background (note that kshdoes 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 / --loginalways 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.
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.
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.
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.
Reacted by Michael Klement, sergei and Staffan Gustafsson
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.
Activity
lzybkr commentedon Apr 19, 2017
It looks like
sh,bash,fish, andzshall support-lto mean it is a logon shell.kshdoes not seem to support this parameter.That said, it looks like
-lis 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
-lwould make things more confusing.mklement0 commentedon Apr 20, 2017
Just to add some more background (note that
kshdoes 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
-lfor sh, all major POSIX-compatible shells support it (dash,bash,ksh,zsh).Note that
fishneither is nor aspires to be POSIX-compatible.-lindeed explicitly creates a login shell, which invariably sources the login profile(s) (e.g.,~/.bash_profilein Bash) - whether the shell is interactive or not.bash,kshandzsh(but notdash) 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
-ieven 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
-noprofilemust 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/--loginalways source their*profilefile(s), even for non-interactive shells.Interactive POSIX-like shells not started with
-l/--loginsource their*rcfile(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
-NoExitswitch.PowerShell's
-Command/-Fileparameters roughly work like their POSIX counterparts (-c/ by default), but there are problematic differences.lzybkr commentedon Apr 20, 2017
Sure enough, I didn't look closely enough at the error message I saw when running
ksh -lunder 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
-noprofileall the time, meaning I can interfere with their scripts easily, on purpose or not.vors commentedon Apr 22, 2017
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"?
powercode commentedon Apr 22, 2017
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.
mklement0 commentedon Apr 22, 2017
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./bin/bashon 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/bashis 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_profileonly.-lto/bin/bashon macOS, which creates a logon shell.These platform differences are unfortunate, but they ultimately go back to the questionable behavior of not also loading
~/.bashrcin an interactive login shell.Arguably, the aspects of login and interactive should be separate: source
~/.bashrcwhenever the shell is interactive (whether also a login shell or not), and source~/.bash_profilewhenever 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
~/.bashrcfrom~/.bash_profile(sometimes complemented with a check inside~/.bashrcthat 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
-NoProfileand-NonInteractive, both of which invert the logic of POSIX-like shells.mklement0 commentedon May 9, 2017
I've created #3743 for a more comprehensive look at aligning the PowerShell CLI with that of POSIX-like shells.
lypanov commentedon Mar 5, 2018
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.
[-]Consider supporting -l as an alias to -noprofile[/-][+]Support `-l` for pwsh.exe[/+]SteveL-MSFT commentedon May 3, 2019
The whole
loginvsnon-loginshell 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-las-LoadProfilewhich is effectively a no-op for now.