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
这不起作用 - 没有产生输出,我的问题为什么不?
也只是输入一些输入TO 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
虽然我还没有解释,但我有一个解决方法可以很好地传输内容:
process.ps1:
begin {if($input){}}
process {
$_
}
看来,如果没有访问begin{}
的$input
块,则不会输入process{}
块。
这可能是一个PowerShell错误,因为它在PowerShell中正常运行。