Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(some) command read from stdin seem to require extra trailing newline #21644

Open
5 tasks done
philcerf opened this issue May 8, 2024 · 4 comments
Open
5 tasks done
Labels
Needs-Triage The issue is new and needs to be triaged by a work group.

Comments

@philcerf
Copy link

philcerf commented May 8, 2024

Prerequisites

Steps to reproduce

I see the following in current PowerShell versions back to the days of powershell.exe.

Having the following files:

$ xxd lf.ps1 
00000000: 4765 742d 5072 6f63 6573 7320 7c0a 5768  Get-Process |.Wh
00000010: 6572 652d 4f62 6a65 6374 207b 245f 2e4e  ere-Object {$_.N
00000020: 616d 6520 2d49 4c69 6b65 2027 2a65 7870  ame -ILike '*exp
00000030: 6c6f 7265 722a 277d 0a                   lorer*'}.
$ xxd crlf.ps1 
00000000: 4765 742d 5072 6f63 6573 7320 7c0d 0a57  Get-Process |..W
00000010: 6865 7265 2d4f 626a 6563 7420 7b24 5f2e  here-Object {$_.
00000020: 4e61 6d65 202d 494c 696b 6520 272a 6578  Name -ILike '*ex
00000030: 706c 6f72 6572 2a27 7d0d 0a              plorer*'}..

(i.e. happens with both, LF and CRLF newlines)

and executing them via -File works as expected:

$ pwsh -File lf.ps1 

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     73    41,08     108,07       8,95    3772   4 explorer

$ pwsh -File crlf.ps1 

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     73    41,08     108,07       8,95    3772   4 explorer

But If I do the same from stdin:

$ pwsh -Command - <lf.ps1 
$ pwsh -Command - <crlf.ps1 

there's no output at all and the exit code is still 0.

It does suddenly work, if I add another trailing newline (either LF or CRLF) at the end of the file.

What also works is:

$ pwsh -Command "Get-Process | 
Where-Object {\$_.Name -ILike '*explorer*'}"

This is executed from bash, and the string passed as argv to -Command contains a LF newline, i.e. binary it looks like:

$ printf '%s' "Get-Process | 
Where-Object {\$_.Name -ILike '*explorer*'}" | xxd 
00000000: 4765 742d 5072 6f63 6573 7320 7c20 0a57  Get-Process | .W
00000010: 6865 7265 2d4f 626a 6563 7420 7b24 5f2e  here-Object {$_.
00000020: 4e61 6d65 202d 494c 696b 6520 272a 6578  Name -ILike '*ex
00000030: 706c 6f72 6572 2a27 7d                   plorer*'}

So if the command is given as string, it works even without terminating newline for the last line.

Any ideas why it doesn't work when reading the command from stdin?

btw: I do the this on Windows and invoking Cygwin.

Thanks,
Philippe

Expected behavior

Should execute the command.

Actual behavior

Doesn't execute the command, or at least produces no output.

Error details

No response

Environment data

$ echo "$PSVersionTable" | pwsh -Command -

gives no output either ;-)



### Visuals

_No response_
@philcerf philcerf added the Needs-Triage The issue is new and needs to be triaged by a work group. label May 8, 2024
@philcerf
Copy link
Author

philcerf commented May 8, 2024

btw: The background to this is that I wanted to be able to start scripts from a shell script like in:

$ pwsh -Command - <'END'
some powershell script
goes here
END

@philcerf
Copy link
Author

philcerf commented May 8, 2024

Oh and I should mention why I titled "(some) commands":

E.g. just

$ pwsh -Command - <<'END'
Get-Process
END

seems to work fine, even without the extr newline before the END, that makes the above script working.

@philcerf
Copy link
Author

philcerf commented May 8, 2024

Just noted, that it doesn't need to be an extra newline to make it work. Seems any even non-newline-terminated character after the newline from the last actual command line makes it work.

For example, the following doesn't work:

cmd="$( cat <<'END'
Get-Process |
Where-Object {$_.Name -ILike '*explorer*'}
END
)"

printf '%s\n' "$cmd" | powershell -Command -

while when there's an extra space (or e.g. \n) after the \n it works:

cmd="$( cat <<'END'
Get-Process |
Where-Object {$_.Name -ILike '*explorer*'}
END
)"

printf '%s\n ' "$cmd" | powershell -Command -

Interestingly, it seems if the extra char is missing, then powershell doesn't even execute the command. Originally I had a quoting error in my code (the \ before the $).

In:

cmd="$( cat <<'END'
Get-Process |
Where-Object {\$_.Name -ILike '*explorer*'}
END
)"

printf '%s\n' "$cmd" | powershell -Command -

No error messages are printed, while in:

cmd="$( cat <<'END'
Get-Process |
Where-Object {\$_.Name -ILike '*explorer*'}
END
)"

printf '%s\n ' "$cmd" | powershell -Command -

there are.

@mklement0
Copy link
Contributor

mklement0 commented May 9, 2024

As noted in #3223, it is multiline statements that need an extra trailing newline in order to be recognized as a complete statement by the REPL-like behavior exhibited by -Command -, but the linked issue was aimed at a more fundamental fix: doing away with the REPL behavior, which turned out not to be an option due to backward compatibility.

So, thank your opening this a separate issue, which can be dealt with in the context of the by-design REPL behavior.
(I don't have an explanation for why a space in lieu of an extra newline seemingly also works from Bash.)

The extra trailing newline required to terminate a multiline statement appears to be by design (the same behavior applies in an interactive session with PSReadLine unloaded).

The real bug here is that an incomplete statement is ignored; quoting @SeeminglyScience from #15331 (comment):

Looks like the logic for handling IncompleteInput parse errors isn't there. That should probably be its own issue (if it isn't already). Also probably should print parse errors for that matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs-Triage The issue is new and needs to be triaged by a work group.
Projects
None yet
Development

No branches or pull requests

2 participants