从CMD到PowerShell的管道

时间:2019-04-14 11:53:40

标签: powershell

TLDR:为什么不能在两个POWERSHELL.exe实例之间通过管道传输输出?

我想拖一个input.txt文件并将其内容通过管道传递到接受STDIN的任何 CLI。使用者可以是PowerShell.exe,php.exe,awk,python,sed等。

我的假设是STDIN和STDOUT是所有CLI都讲的通用概念,因此我应该能够愉快地从CMD / DOS命令传送到POWERSHELL.exe。

input.txt:

hello
world

我希望的操作模式是,将行添加到input.txt时,它们会立即通过管道传递到接受STDIN的CLI。在PowerShell中,可以将其模拟为:

Get-Content -Wait input.txt | ForEach-Object {$_}

除了我不需要的额外换行符之外,它可以按我的意愿工作:

hello
world

I'm adding lines and saving and...

...they appear here...

yaaaay

现在,我将这种尾部功能封装为tail.ps1,然后制作一个简单的使用者脚本process.ps1,将其链接在一起:

tail.ps1:

Get-Content -Watch .\input.txt

process.ps1:

process {
   $_
}

我明确地使用process{}块是因为我想要流式管道而不是某些end{}块循环。

同样,这可以在PowerShell Shell中运行:

PS> .\tail.ps1 | .\process.ps1
hello
world

here is a new line saved to input.txt

现在,我想将每个脚本视为一个单独的CLI,可以从CMD / DOS中调用它:

C:\>POWERSHELL -f tail.ps1 | POWERShell -f process.ps1

这不起作用-没有产生任何输出,我的问题是为什么??

也仅将一些输入传递给powershell.exe process.ps1不会产生任何输出:

C:\>type input.txt | POWERSHELL -f process.ps1

但是,将PowerShell从管道传输到AWK确实可行:

C:\>POWERSHELL -f tail.ps1 | awk /e/
Hello
here is a newline with an e
so we're good

AWK为什么接受管道,而POWERShell process.ps1不接受管道?

从CMD / DOS运行的另一个令人困惑的示例:

C:\>powershell -c "'hello';'world'"
hello
world       << This is as it should be
C:\>powershell -c "'hello';'world'"  | powershell -f process.ps1
            << No output appears - why not!?
W:\other>powershell -c "'hello';'world'"  | powershell -c "$input"
hello
world       << Powershell does get the stdin

1 个答案:

答案 0 :(得分:0)

我有一个变通办法,尽管我还没有解释,但可以很好地使事情流化:

process.ps1

begin {if($input){}}
process {
    $_
}

似乎没有访问begin{}的{​​{1}}块,没有输入$input块。

这很可能是PowerShell的错误,因为它可以在Powershell中正常运行。