我使用此命令查看控制台和文件中的输出:
powershell -command "my_command_1 | tee ('logs\{0}.log' -f (Get-Date -format 'yyyy.MM.dd-HH.mm'))"
powershell -command "my_command_2 | tee ('logs\{0}.log' -f (Get-Date -format 'yyyy.MM.dd-HH.mm'))"
# etc
它的效果不如我预期的那样好,我有一些疑问:
- 我如何将 stderr 重定向到文件?
输出工作得非常奇怪。对于某些命令,在打印文本和更新控制台/文件之间存在巨大的延迟。对于其他一些命令,在打印文本时输出似乎已更新(我运行没有 tee 的命令,我知道它应该打印什么)。这种延迟使这个 tee 几乎毫无用处 - 如果打印了一些严重错误,我需要停止命令,但直到为时已晚我才看到任何东西,该怎么办?
对于某些命令,仅当完整个命令完成后才会打印输出。
- 此外,即使命令要求用户输入,控制台/文件输出也是空的!对于该命令,我知道它期望什么,并盲目地打印所需的文本,它成功了,但对于其他命令 - 没有输出,我将无限地等待某些事情发生,而命令将等待我的输入!
这些问题有解决方案吗?如果没有,PowerShell 中的这个 tee 东西就完全没用了。
答案1
My-Command 2>&1 | Tee-Object 'myfile.log'
。 看Get-Help about_Redirection
。- 您应该捕获错误,而不是依赖Ctrl+ C。请参阅
Get-Help about_Try_Catch_Finally
。您正在运行的命令是外部程序还是脚本? - 据我所知,通常字符串对象不会在到达行尾字符之前发送到管道中。原因很简单:如果不这样做,部分(读作:不完整)字符串将发送到管道中。
Tee
可能会很好地处理部分字符串,但其他 cmdlet (如ForEach-Object
或)Select-Object
肯定不会。请注意,Get-Content
有一个特殊的开关-ReadCount
可以在一定程度上覆盖此行为,并且会严重干扰Select-Object -Skip/-First/-Last/-Unique
管道下方的命令。
很可能您正在运行的外部程序不会遵守 PowerShell 所期望的约定。Tee
例如,正确调用的是Tee-Object
,这应该会告诉您它擅长处理哪些事情。在这种情况下,您可能更进一步tee.exe
从GNU Win32 实用程序或者管理系统其设计目的是立即转发内容。