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
{{ message }}
Repository navigation
exit status 0 on syntax errors, when reading scrip from stdin #21784
Fundamentally, a parser error cannot be handled with runtime constructs such as $ErrorActionPreference = "Stop" and try / catch.
It is the statement-by-statement, REPL-like processing exhibited by -Command - that isolates a parser error to a given statement, but the fact that a parser error in the last statement doesn't result in a nonzero exit code should indeed be considered a bug, as argued in detail in #21808 (comment)
rhubarb-geek-nz Well I guess my reply would be mostly what I've wrote over in the other ticket, i.e. that it's at least undocumented, that - for -Command and -File make them behave completely differently than with values other than -... but more practically spoken: it seems not so good design with, to have a single option, e.g. -Command behave so dramatically different just by changing the source of the data.
If there'd really be a need for a mode of that semi-interactive parsing, it would IMO be better to have separate option for that and not for -Command which behaves just as expected with real commands given.
Michael Klement (@mklement0) My main point here wasn't about the try not working (which I think is obvious in case of a syntax error), it was about 0 being returned despite the syntax error... so a caller has no chance of knowing that it didn't work.
The Interactive WG discussed this. The feature -Command - is designed to imitate a REPL, so the behavior is by design. While we understand and agree that this feature should have been appropriately named to indicate the functionality it offers (which is unfortunately different than how most applications handle -), we cannot change this now.
Philippe Cerfon (@philcerf), to bring closure to the specific aspect of the -Command - behavior that prompted this issue (the exit code):
As it turns out, the observed behavior is actually consistent with the pseudo-interactive, REPL-like behavior (which has just been declared to be by design), and the reason is now mentioned in the doc-update PR that Sean Wheeler (@sdwheeler) has since submitted:
An interactively submitted, syntactically broken command - i.e. one that cannot even be parsed - does not cause $? to be set: the previous (non-broken) command's $? value remains in effect.
However, with -Command it is the value of $? value after the last statement executed that translates into the process exit code ($true -> 0, $false -> 1); thus, if $? happened to be $truebefore executing the syntactically broken command, 0 ends up getting reported as the exit code.
A simple example:
@'# If you uncomment the following statement, $LASTEXITCODE will be 1, because it is then# this command's $? value that determines the exit code.# 1 / 0& { 1 / # This syntactically broken command has NO impact on the exit code.}'@| pwsh -NoProfile -Command -; $LASTEXITCODE# -> 0(!)
It follows that if you use the workaround to make -Command - behave like a script (enclose all code in & { ... } and append an extra newline), $LASTEXITCODE will always be 0 if the code is syntactically broken.
While the -Command behavior is consistent with the interactive experience it replicates, you could argue that it would make more sense to make parsing errors cause $? to reflect $false too, not just runtime errors.
While this wouldn't be much of an improvement in a true interactive session, it would help in the -Command - case when -Command - is used with the behave-like-a-script workaround.
TBH, I kinda stopped following these issues a bit, because the general way they seem to be dealt with is:
defining a completely broken behaviour as defective by design and thus allegedly valid.
I mean for me it's not really a big problem, since I simply pass my commands now as a multiline strings argument to -Command and with that, behaviour seems to be more or less what one would expect and what makes sense.
But I guess more people will fall into the traps involved when commands are read (non-interactively) from stdin with a behaviour that probably makes no sense in any situation.
Anyway, thanks for the workaround suggestions, but I rather go by my multiline string argument, because there's always the danger that there's more weird behaviour with the semi-interactive mode which no one can reasonably expect - I mean I found already a handful in just a few days.
Thanks,
Philippe.
microsoft-github-policy-service commented on May 24, 2024
Philippe Cerfon (@philcerf), yes, using -Command with the code as a direct string argument is the safest choice.
The current behavior does have its uses, but they're exotic and to me they never should have been exposed via -File - or -Command -, given the different behavior that users justifiably expect (at least in the -File - case; from the read-all-input-and-treat-it-as-a-script expectation, there's no need to also support -Command -).
I just remembered that there was a discussion about providing a new CLI entry point under a different name, say, pwsh-np, originally prompted by not wanting to load profiles by default (another notably deviation from what POSIX-compatible shells do).
Such a new CLI entry point would be an opportunity to address a number of issues with the current CLI, compiled in #23872 (which was just converted to a discussion from #8072, so I'm not holding my breath), to which I've just added the issue at hand.
Follow-up from a conversation with Steve Lee (@SteveL-MSFT) in #7989. PowerShell's existing CLI has a number of problems, relating to: (a) unconditionally dot-sourcing $PROFILE, making for unpredictable execut...
Activity
mklement0 commentedon May 9, 2024
Fundamentally, a parser error cannot be handled with runtime constructs such as
$ErrorActionPreference = "Stop"andtry/catch.It is the statement-by-statement, REPL-like processing exhibited by
-Command -that isolates a parser error to a given statement, but the fact that a parser error in the last statement doesn't result in a nonzero exit code should indeed be considered a bug, as argued in detail in #21808 (comment)philcerf commentedon May 10, 2024
rhubarb-geek-nz Well I guess my reply would be mostly what I've wrote over in the other ticket, i.e. that it's at least undocumented, that
-for-Commandand-Filemake them behave completely differently than with values other than-... but more practically spoken: it seems not so good design with, to have a single option, e.g.-Commandbehave so dramatically different just by changing the source of the data.If there'd really be a need for a mode of that semi-interactive parsing, it would IMO be better to have separate option for that and not for
-Commandwhich behaves just as expected with real commands given.Michael Klement (@mklement0) My main point here wasn't about the
trynot working (which I think is obvious in case of a syntax error), it was about0being returned despite the syntax error... so a caller has no chance of knowing that it didn't work.mklement0 commentedon May 10, 2024
Yes. That's why I said that what you've uncovered should indeed be considered a bug.
SeeminglyScience commentedon May 22, 2024
The Interactive WG discussed this. The feature
-Command -is designed to imitate a REPL, so the behavior is by design. While we understand and agree that this feature should have been appropriately named to indicate the functionality it offers (which is unfortunately different than how most applications handle-), we cannot change this now.mklement0 commentedon May 23, 2024
Philippe Cerfon (@philcerf), to bring closure to the specific aspect of the
-Command -behavior that prompted this issue (the exit code):As it turns out, the observed behavior is actually consistent with the pseudo-interactive, REPL-like behavior (which has just been declared to be by design), and the reason is now mentioned in the doc-update PR that Sean Wheeler (@sdwheeler) has since submitted:
An interactively submitted, syntactically broken command - i.e. one that cannot even be parsed - does not cause
$?to be set: the previous (non-broken) command's$?value remains in effect.However, with
-Commandit is the value of$?value after the last statement executed that translates into the process exit code ($true->0,$false-> 1); thus, if$?happened to be$truebefore executing the syntactically broken command,0ends up getting reported as the exit code.A simple example:
It follows that if you use the workaround to make
-Command -behave like a script (enclose all code in& { ... }and append an extra newline),$LASTEXITCODEwill always be0if the code is syntactically broken.While the
-Commandbehavior is consistent with the interactive experience it replicates, you could argue that it would make more sense to make parsing errors cause$?to reflect$falsetoo, not just runtime errors.While this wouldn't be much of an improvement in a true interactive session, it would help in the
-Command -case when-Command -is used with the behave-like-a-script workaround.philcerf commentedon May 23, 2024
TBH, I kinda stopped following these issues a bit, because the general way they seem to be dealt with is:
defining a completely broken behaviour as defective by design and thus allegedly valid.
I mean for me it's not really a big problem, since I simply pass my commands now as a multiline strings argument to
-Commandand with that, behaviour seems to be more or less what one would expect and what makes sense.But I guess more people will fall into the traps involved when commands are read (non-interactively) from stdin with a behaviour that probably makes no sense in any situation.
Anyway, thanks for the workaround suggestions, but I rather go by my multiline string argument, because there's always the danger that there's more weird behaviour with the semi-interactive mode which no one can reasonably expect - I mean I found already a handful in just a few days.
Thanks,
Philippe.
microsoft-github-policy-service commentedon May 24, 2024
This issue has been marked as by-design and has not had any activity for 1 day. It has been closed for housekeeping purposes.
microsoft-github-policy-service commentedon May 24, 2024
📣 Hey Philippe Cerfon (@philcerf), how did we do? We would love to hear your feedback with the link below! 🗣️
🔗 https://aka.ms/PSRepoFeedback
mklement0 commentedon May 29, 2024
Philippe Cerfon (@philcerf), yes, using
-Commandwith the code as a direct string argument is the safest choice.The current behavior does have its uses, but they're exotic and to me they never should have been exposed via
-File -or-Command -, given the different behavior that users justifiably expect (at least in the-File -case; from the read-all-input-and-treat-it-as-a-script expectation, there's no need to also support-Command -).I just remembered that there was a discussion about providing a new CLI entry point under a different name, say,
pwsh-np, originally prompted by not wanting to load profiles by default (another notably deviation from what POSIX-compatible shells do).Such a new CLI entry point would be an opportunity to address a number of issues with the current CLI, compiled in #23872 (which was just converted to a discussion from #8072, so I'm not holding my breath), to which I've just added the issue at hand.