如何在 Windows 命令行中通过管道传输并显示输出?

如何在 Windows 命令行中通过管道传输并显示输出?

我需要在批处理文件中运行一个进程。该进程会产生一些输出。我需要将该输出显示在屏幕上将其发送(管道)到另一个程序。

bash 方法用途tee

echo 'ee' | tee /dev/tty | foo

Windows 有类似产品吗?如有必要,我很乐意使用 PowerShell。

tee适用于 Windows 的端口,但似乎没有等效的端口/dev/tty,这使问题变得复杂。


这里的具体用例:我有一个需要运行的程序 (launch4j),向用户显示输出。同时,我需要能够检测脚本中的成功或失败。不幸的是,这个程序没有设置退出代码,我无法强制它这样做。我目前的解决方法是将管道连接到find,以搜索输出 (launch4j config.xml | find "Successfully created" ) - 但是,这会吞掉我需要显示的输出。因此,我需要某种方式来同时显示到屏幕上并将输出发送到命令 -此命令应该能够设置ERRORLEVEL(它不能异步运行)。这将用于构建脚本,该脚本可以在许多不同的机器上运行。

对于这种特殊情况,需要一些轻量级的东西 - 我无法安装额外的框架或解释器(例如 perl 按照建议这个答案)。另外,任何商业程序都必须具有允许重新分发的许可证。

答案1

您可以尝试编译此代码并像这样使用它:echo something | mytee | foo
我不知道它是否会起作用,因为我不知道 Windows 如何处理stderr/ stdout,但它可能会起作用。

#include <stdio.h>
int main()
{
    int c;
    while((c = fgetc(stdin)) != EOF)
    {
        printf("%c", c);
        fprintf(stderr, "%c", c);
    }
    return 0;
}

答案2

我能想到的一个有点混乱的方法是使用其中一个移植tee程序,保存到一个临时文件,然后使用 测试该文件find。但是,使用临时文件可能是不可取的。

如果 PowerShell 是一个选项,它实际上有一个Tee-Outputcmdlet。它不像 bash 示例那么直接,但它可以-Variable选择将输出保存到变量中,然后可以进行搜索:

# save result in $LastOutput and also display it to the console
echo "some text" | Tee-Output -Variable LastOutput

# search $LastOutput for a pattern, using Select-String
# instead of find to keep it within PowerShell
$Result = $LastOutput | Select-String -Quiet "text to find"

# $Result should contain either true or false now
# this is the equivalent of batch "if errorlevel 1"
if ($Result -eq $True) {
    # the string exists in the output
}

为了回答更普遍的问题,也可以将变量导入任何其他程序,然后设置$LastExitCode。作为可以从基本命令行调用的一行代码:powershell -c "echo text | Tee-Object -Variable Result; $Result | foo"

答案3

为什么不直接在 PowerShell 中执行命令Invoke-Command并将结果捕获到变量中呢?如果存在结果,您可以在变量中搜索结果,执行某些操作,然后将所有输出显示到控制台。

用于捕获输出的测试文件只是包含以下文本的记事本(C; \ Temp \ OutputTest.txt):

blahlbalsdfh
abalkshdiohf32iosknfsda
afjifwj93f2ji23fnsfaijfafds
fwjifej9f023f90f3nisfadlfasd
fwjf9e2902fjf3jifdsfajofsda
jfioewjf0990f
Successfully Created
fsjfd9waf09jf329j0f3wjf90awfjw0afwua9

在你的情况下,虽然你会像我相信的那样调用你的命令{& "Launch4j" config.xml},但对于我的例子来说:

Invoke-Command -ScriptBlock {Get-Content C:\temp\OutputTest.txt} | foreach {
$_;
if ($_ -match "successfully created") {$flag = $true}
}
if ($flag) {
"do whatever"
}

答案4

您可以将批处理文件重写为 PowerShell 脚本。PowerShell 具有Tee-Object(别名为Tee)。

参数集:文件 Tee-Object [-FilePath] [-Append] [-InputObject ] [ ]

参数集:LiteralFile Tee-Object -LiteralPath [-InputObject ] [ ]

参数集:变量 Tee-Object -Variable [-InputObject ] [ ]

相关内容