我正在通过批处理文件运行服务器,并且希望服务器输出既显示在屏幕上,又写入日志文件。我找到了一种方法来做到这一点这个答案:
powershell "startmyserver | tee server.log"
问题是管道导致第一个命令在第二个命令运行之前运行并完全完成。这意味着我无法在服务器实际运行时监视服务器的标准输出,而这正是我想要做的(我不想为了检查最新的日志消息而关闭服务器)。
为了举一个更简单的例子,我尝试了pause
。嗯,pause
在 Powershell 上不存在,所以我必须在嵌套的cmd
shell 中运行它:
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"
在我的适度测试中,输出生成得太快了,我无法判断它是否按照您指定的方式工作。