|
| 1 | +--- |
| 2 | +RFC: RFC0040 |
| 3 | +Author: Steve Lee |
| 4 | +Status: Draft-Accepted |
| 5 | +SupercededBy: N/A |
| 6 | +Version: 1.0 |
| 7 | +Area: Console |
| 8 | +Comments Due: July 15, 2019 |
| 9 | +Plan to implement: Yes, PS7 |
| 10 | +--- |
| 11 | + |
| 12 | +# Enable PowerShell as Login Shell on POSIX-based systems |
| 13 | + |
| 14 | +POSIX shells on Unix-based systems use a `-l` switch to start the shell as a login shell. |
| 15 | +This means the shell is not being started from an existing configured environment and |
| 16 | +needs to execute `/etc/profile` to populate environment variables along with other |
| 17 | +environment changes. |
| 18 | + |
| 19 | +## Motivation |
| 20 | + |
| 21 | + As a PowerShell user, |
| 22 | + I can use PowerShell as my login shell on Unix-based systems, |
| 23 | + so that I can use PowerShell everywhere. |
| 24 | + |
| 25 | +## Specification |
| 26 | + |
| 27 | +Many existing tools expect `-l` to be accepted by a shell and to act as a login |
| 28 | +shell. |
| 29 | + |
| 30 | +`-l` (expanded form is `-Login`) will: |
| 31 | + |
| 32 | +- On Windows, do nothing as the login shell concept doesn't exist. |
| 33 | + No error, this param is ignored. |
| 34 | +- On Unix based systems, exec `pwsh` using `sh -l` so that the normal login |
| 35 | + shell processing occurs and the environment is pre-populated as expected. |
| 36 | + |
| 37 | +>[!NOTE] |
| 38 | +> The actual path to `sh` would depend on the operating system. |
| 39 | +> For Linux, the path would be `/usr/bin`. |
| 40 | +> For Snap, the path would be `/snap/bin`. |
| 41 | +> For macOS, there is an issue with `sh` not loading the login profile with |
| 42 | +> our usage, so `pwsh` will use `zsh` with `sh` emulation mode to enable |
| 43 | +> proper initialization of the environment. |
| 44 | +
|
| 45 | +Since `pwsh` is simply starting an instance of itself, it should work the same |
| 46 | +regardless if a stable or preview release. |
| 47 | + |
| 48 | +Initial performance tests indicate that `pwsh -l` will incur a 6% startup hit. |
| 49 | +Compared to a pure Bourne shell script which has a 4% startup hit. |
| 50 | +Most of that is simply processing the Bourne shell scripts to setup the environment. |
| 51 | +As such, there is a relative 2% additional perf hit with this proposal. |
| 52 | + |
| 53 | +The impact seems acceptable given that the login shell is typically the first |
| 54 | +shell you create and subsequent use of `pwsh` would not be a login shell. |
| 55 | + |
| 56 | +In addition, `pwsh` will need to be updated to detect if it was started with |
| 57 | +a hyphen (for example, `-pwsh`) as that is another way that Unix based operating |
| 58 | +systems start the default login shell and doesn't necessarily use `-l`. |
| 59 | + |
| 60 | +On Linux, this will be implemented by inspecting `/proc` on the filesystem. |
| 61 | +On macOS, this will be implemented by calling `sysctl()` getting the process |
| 62 | +information for the current process and inspecting `argv[0]`. |
| 63 | + |
| 64 | +## Alternate Proposals and Considerations |
| 65 | + |
| 66 | +### Process /etc/profile using sh and copy the env vars |
| 67 | + |
| 68 | +This proposal would be that if `-l` is specified, pwsh would run `/bin/sh -l -c export` |
| 69 | +which would create a new shell process that does all the processing needed for |
| 70 | +a login shell and export the environment variables that would be exported. |
| 71 | +Additional code is needed to take those environment variables and copy them to |
| 72 | +the parent pwsh process. |
| 73 | + |
| 74 | +The downsides to this approach is additional code to maintain, |
| 75 | +but more importantly not getting a complete login shell environment as things |
| 76 | +like ulimit and umask would not be inherited into pwsh. |
| 77 | + |
| 78 | +### `pwsh-login` script |
| 79 | + |
| 80 | +This proposal would be to include a Bourne shell script called `pwsh-login` |
| 81 | +that would contain: |
| 82 | + |
| 83 | +```sh |
| 84 | +#!/bin/sh -l |
| 85 | +exec /usr/local/bin/pwsh "$@" |
| 86 | +``` |
| 87 | + |
| 88 | +The location of `sh` would depend on the specific operating system. |
| 89 | + |
| 90 | +The perf impact of this compared to starting pwsh as a non-login shell is |
| 91 | +approximately 4%. |
| 92 | + |
| 93 | +### Supporting different default login shells |
| 94 | + |
| 95 | +In the future, if relying on `sh` (and thus `/etc/profile`) is not sufficient, |
| 96 | +we can allow an optional argument to `-login` to indicate the shell to use |
| 97 | +to process the script that creates the environment. |
| 98 | + |
| 99 | +### macOS moving to Zsh by default |
| 100 | + |
| 101 | +Expectation is that macOS intends to switch to `zsh` as the default shell so |
| 102 | +it may make sense to revisit this in the future to default to using `zsh` so |
| 103 | +that `zprofile` gets processed. |
0 commit comments