powershell stdin pipes and redirection

Viewed 492

Hello so I have been making a small cross platform script I can curl and pipe into bash and Powershell. The basic idea is the server sends a command to the interpreter and then it gives a command to redirect all output after to stdout. An example in bash is

#some commands 
aplay rick.wav
cat -
random text
that will be redirected to stdout by cat... 
bash will never see this

I would then pipe this to stdin of bash

But for Powershell I can do cat test.ps1 | iex or cat test.ps1 | powershell - But can't redirect stdin to stdout continuously in one command like cat - because cat doesn't look from stdin.

Also some side notes after trying a lot of random things it seems like there are many stdin types for Windows, one being keyboard and another being pipes

1 Answers

You can pipe lines of text to powershell.exe, the Windows PowerShell CLI, via -Command - (-c -), and it will interpret them one by one.

Here's an interactive demonstration from inside PowerShell; it works the same with input piped (provided via stdin) from the outside:

# Repeatedly prompt for a line of input and execute it as a PowerShell command.
# Press Ctrl-C to exit.
& { while ($true) { Read-Host } } | powershell -noprofile -c -

Note:

  • -Command - has problematic aspects, notably with commands that span multiple lines (an additional Enter keystroke / newline is then needed for the command to be recognized) and so does -File -, whose behavior is even stranger - see this answer and GitHub issue #3223.

Another demonstration, simulating outside stdin input via 2 lines piped to powershell -c -:

'get-date', 'get-item /' | powershell -noprofile -c -

The two commands are executed and their output is printed; powershell.exe then exits, because no more stdin input is available; however, with indefinite stdin input (analogous to cat - on Unix-like platforms) the PowerShell process would be kept alive indefintely too.

Related