我需要在批处理文件中运行一个进程。该进程会产生一些输出。我需要将该输出显示在屏幕上和将其发送(管道)到另一个程序。
这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-Output
cmdlet。它不像 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 ] [ ]