Windows 中通过管道逐行输出命令行

Windows 中通过管道逐行输出命令行

我正在通过批处理文件运行服务器,并且希望服务器输出既显示在屏幕上,又写入日志文件。我找到了一种方法来做到这一点这个答案

powershell "startmyserver | tee server.log"

问题是管道导致第一个命令在第二个命令运行之前运行并完全完成。这意味着我无法在服务器实际运行时监视服务器的标准输出,而这正是我想要做的(我不想为了检查最新的日志消息而关闭服务器)。

为了举一个更简单的例子,我尝试了pause。嗯,pause在 Powershell 上不存在,所以我必须在嵌套的cmdshell 中运行它:

powershell "cmd /c pause | tee test.txt"

不出所料,执行此命令后,我只看到一个闪烁的光标。过了一会儿,我按下一个键,然后出现“按任意键继续”并几乎同时写入文件。

我希望管道将 stdout 逐行传输到下一个命令。换句话说,每当遇到 EOL 字符时,它都应该发送一些输出,这应该(在我的情况下tee)导致文本出现在屏幕上并同时写入文件。(事实上,我甚至不关心文本是否逐行写入文件,它可以全部写入最后,尽管这不是理想的。我只是希望能够在屏幕上看到它们被写入。)

这在命令提示符和/或 Powershell 中可行吗?

答案1

这个问题解释于 堆栈溢出 事实上,PowerShellTee-Object不会刷新输出流,而只是等待源执行此操作,因此您会在操作结束时获得输出。这是设计使然。

答案中提出的解决方法是使用以下代码:

./program | ForEach-Object {
    Write-Host $_
    $_
} | Set-Content program.log

如果上述方法不起作用,可以尝试另一种方法:

./program | ForEach-Object {
    [Console]::WriteLine($_)
    [Console]::Out.Flush()
    $_
} | Set-Content program.log

因此命令如下:

PowerShell -ExecutionPolicy Unrestricted "startmyserver | ForEach-Object { Write-Host $_; $_} | Set-Content server.log"

在我的适度测试中,输出生成得太快了,我无法判断它是否按照您指定的方式工作。

相关内容