【问题标题】:Writing errors and output to a text file and Console将错误和输出写入文本文件和控制台
【发布时间】:2010-06-09 18:06:48
【问题描述】:

我正在尝试将执行脚本的整个输出(包括错误)同时写入控制台和文件。我尝试了几种不同的选择:

.\MyScript.ps1 | tee -filePath C:\results.txt # only the output to the file
.\MyScript.ps1 2> C:\results.txt # only the errors to the file and not the console
.\MyScript.ps1 > C:\results.txt # only the output to the file and not the console 

我希望我可以使用该文件来查看输出/错误。

编辑:

这是我当前的测试脚本。期望的结果是可以看到所有三个消息。

function Test-Error 
{
    echo "echo"
    Write-Warning "warning"
    Write-Error "error"       
}

Test-Error 2>&1 | tee -filePath c:\results.txt

【问题讨论】:

  • @JasonMArcher 感谢您更新此问题的标签!既然它已在 V3 中修复并且我最初使用的是 V2,我们应该做些什么额外的事情吗?谢谢。
  • 这取决于,您只想要 V2 的答案吗?这不是 V2 特有的问题。因此,最好的办法是优先使用它们所针对的 PowerShell 版本的实际答案。 :)
  • 我在现有答案中添加了一些关于 PS 版本兼容性的注释。

标签: powershell redirect


【解决方案1】:

你试过了吗:

 .\MyScript.ps1 2>&1 | tee -filePath c:\results.txt

2>&1 就是你要找的东西

注意:此答案在 PowerShell 1.0 和 2.0 中效果很好,但在 PowerShell 3.0 及更高版本中只会捕获标准输出和错误。

【讨论】:

  • 这非常接近。我将用于测试我想要的功能的脚本添加到问题中。它能够获得标准输出和错误,但不能获得警告。还有其他想法吗?
  • 你没有很多好的选择。阅读有关 WRite-Warning 和 Write-Error 的 cmdlet 帮助主题,您会发现它们根本不同。 Write-Warning 写入主机,Write-Error 写入错误输出流。您可以重定向流,但写入主机会转到主机。您唯一的选择是WarningVariable 等常用参数。您应该能够使用它使所有警告/错误/输出数据重定向到变量。有关详细信息,请参阅 about_CommonParameters 帮助主题。
  • 顺便说一句,看起来你不是第一个遇到这个问题的人。我曾经一起工作的人在这里很好地描述了这个问题:keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!6926.entry
  • Keith 使用的解决方案对我们来说应该是一种临时解决方案。看来我需要重新考虑我们如何在 cmdlet 中登录。感谢您的帮助。
  • 从 PowerShell 3 开始,您可以这样做:.\MyScript.ps1 *>&1 | tee -filePath c:\results.txt,这意味着重定向所有输出流,因为存在警告、调试和详细信息。见about_Redirection
【解决方案2】:

我对找到的任何答案都不满意,所以我混合了一些并想出了这个(在 PowerShell 3.0+ 中):

$output = try{your_command *>&1}catch{$_}

通过它,您可以捕获尝试使用your_command 生成的所有错误和输出。

当你使用不存在的命令时它会捕获异常:

PS C:\Users\jdgregson> $output = try{your_command *>&1}catch{$_}
PS C:\Users\jdgregson> echo $output
your_command : The term 'your_command' is not recognized as the name of a
cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
At line:1 char:15
+ $output = try{your_command 2>&1}catch{$_}
+               ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (your_command:String) [], Comman
   dNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\Users\jdgregson>

当您将无效参数传递给现有命令时,它会捕获异常:

PS C:\Users\jdgregson> $output = try{cat C:\invalid-path.txt *>&1}catch{$_}
PS C:\Users\jdgregson> echo $output
cat : Cannot find path 'C:\invalid-path.txt' because it does not exist.
At line:1 char:15
+ $output = try{cat C:\invalid-path.txt 2>&1}catch{$_}
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\invalid-path.txt:String) [Ge
   t-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetCo
   ntentCommand

如果您的命令完全没有问题,它会捕获输出:

PS C:\Users\jdgregson> $output = try{cat C:\valid-path.txt *>&1}catch{$_}
PS C:\Users\jdgregson> echo $output
this file is really here

它也适用于您的示例:

PS C:\Users\jdgregson> $output = try{Test-Error *>&1}catch{$_}
PS C:\Users\jdgregson> echo $output
echo
WARNING: warning
Test-Error : error
At line:1 char:15
+ $output = try{Test-Error *>&1}catch{$_}
+               ~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorExcep
   tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
   n,Test-Error

【讨论】:

    【解决方案3】:

    默认情况下,只有 Success 数据流被传递到输出文件。要引导错误和警告,您必须添加如下内容:

    你的脚本 3>&1 2>&1 |输出文件 log.txt

    【讨论】:

    【解决方案4】:

    我无法在同一个文件中同时得到错误和结果。对我有用的解决方法:

    .\MyScript.ps1 2> C:\errors.txt | tee -filePath C:\results.txt

    更新: 我做了进一步的工作,我在我的模式下使用了Start-TranscriptStop-Transcript 来捕获所有内容,并且成功了!

    【讨论】:

    • 另一个答案正确地将标准错误和标准输出写入文件。最初的问题是不能同时包含警告。 Start-TranscriptStop-Transcript 非常有用,仍然值得学习。