-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Description
Follow-up from #11461.
When using the PowerShell CLI with -c
/ -Command
, PowerShell by design sets its exit code based on the success status of the last statement executed in the specified command string.
If the last statement is a PowerShell command, success can only be derived from the automatic success-status variable, $?
. As a Boolean, the only sensibly way to map that to an exit code is to map $true
to 0
, and $false
to 1
- this works as expected.
However, if the last statement is a call to an external program, a process exit code is directly available from the child process in which the external program executed, as reflected in automatic variable $LASTEXITCODE
. The same potentially applies to a call to an (in-process) call to a *.ps1
script that uses exit <n>
.
Given that $LASTEXITCODE
can contain more specific information than just abstract success vs. failure, it makes sense to preserve this specific information in the caller's $LASTEXITCODE
value instead of mapping it in a lossy manner to either 0
($LASTEXITCODE
being 0
) or 1
(any nonzero $LASTEXITCODE
value) - which is what currently happens.
While this would technically be a breaking change, it seems to me that it falls into Bucket 3: Unlikely Grey Area:
-
In the typical case, code checks for abstract success vs. failure of child processes, which means that any nonzero exit code indicates failure, without regard to the specific nonzero value.
-
The proposed change wouldn't interfere with that, while at the same time providing more specific information to code that does care about the specific nonzero exit code reported.
Steps to reproduce
On Unix:
& { pwsh -noprofile -c 'sh -c ''exit 5'''; $LASTEXITCODE } | Should -Be 5
Expected behavior
The test should pass.
Actual behavior
The test fails, because the process exit code 5
was unexpectedly mapped to 1
in the caller's scope:
Expected 5, but got 1.
Environment data
PowerShell Core 7.1.0-preview.6