从CMD管道到PowerShell

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从CMD管道到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

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

也只是输入一些输入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中正常运行。

以上是关于从CMD管道到PowerShell的主要内容,如果未能解决你的问题,请参考以下文章

使用 cmd.exe 或 PowerShell 或 Python 从 Windows 命名管道中读取

在 CMD 和 PowerShell 中管道时的不同行为和输出

在 CMD 和 PowerShell 中管道时的不同行为和输出

如何从PowerShell命令行转义管道字符以传递到非PowerShell命令

使用 C/C++ 通过管道到/从 Powershell 设置 UTF-8 输入并获取 UTF-8 输出

管道文件到 uglifyjs - 来自 Powershell