gpt4 book ai didi

git - 从外部命令向stderr写入时不要抛出PowerShell异常

转载 作者:行者123 更新时间:2023-12-02 22:11:07 27 4
gpt4 key购买 nike

当外部命令(例如git)写入stderr时,PowerShell会生成NativeCommandError异常。我希望看到输出和stdout正常,类似于标准UNIX/Linux系统上的输出。该脚本需要运行许多 native 命令,我希望有一种解决方案,该解决方案在可能的情况下不会给每个命令增加过多的困惑和维护。

在Linux上,可以按以下方式 check out 分支:

$ git checkout devel
Branch 'devel' set up to track remote branch 'devel' from 'origin'.
Switched to a new branch 'devel'

最微妙的部分是,无论出于何种原因,最后一行都写到了stderr上。但是,git的退出状态为零,表明成功。在PowerShell下,我得到以下信息:
PS> git checkout devel
Branch 'devel' set up to track remote branch 'devel' from 'origin'.
git : Switched to a new branch 'devel'
At line:1 char:1
+ git checkout devel
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Switched to a new branch 'devel':String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

正在检查 $LASTEXITSTATUS,它显示为零,指示结帐成功。但是,由于git的行为是向stderr写入某些消息,因此它会触发PowerShell注册错误。我可以只 stash 消息并手动检查退出状态,但是我不想在显示错误消息时 stash 它们。此命令可避免出现以下异常:
PS> git checkout devel 2>$null
Branch 'devel' set up to track remote branch 'devel' from 'origin'.

这是StackOverflow上其他答案的建议,但不是我所需要的。我尝试将stderr重定向到stdout,希望PowerShell可以在stdout上看到所有输出,并且不会触发异常,但是它仍然可以:
git checkout devel 2>&1
Branch 'devel' set up to track remote branch 'devel' from 'origin'.
git : Switched to a new branch 'devel'
At line:1 char:1
+ git checkout devel 2>&1
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Switched to a new branch 'devel':String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

我也 try catch 异常,但是try..catch块似乎没有阻止它:
PS> Try { git checkout devel 2>&1 } catch { echo "There was an error, ignore" }
Branch 'devel' set up to track remote branch 'devel' from 'origin'.
git : Switched to a new branch 'devel'
At line:1 char:7
+ Try { git checkout devel 2>&1 } catch { echo "There was an error, ign ...
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Switched to a new branch 'devel':String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

我只希望 native 命令在退出状态为非零时导致失败,而不是仅写入stderr时导致失败。如何防止PowerShell脚本中的 native 命令在写入stderr时引发异常而不完全阻止stderr?

最佳答案

tl;博士

以下是PowerShell ISE 的最简单的解决方法(在常规控制台或Visual Studio Code中不需要):

# Redirect stderr (2) to the success stream (1).
# Doing so wraps stderr lines in [System.Management.Automation.ErrorRecord]
# instances; calling .ToString() on them returns them as normal text.
# CAVEAT: BE SURE THAT $ErrorActionPreference = 'Stop' is NOT IN EFFECT.
git checkout devel 2>&1 | % ToString

有关其他变通方法,包括能够按来源流区分线的功能,请参见 this answer

但是,您 最好改用Visual Studio Code 作为您的开发环境,这从根本上解决了该问题-参见下文。

两个方面:
  • 您所看到的是非终止错误,不是异常(虽然.NET异常是PowerShell的错误处理的基础,但它们始终包装在[System.Management.Automation.ErrorRecord]实例中,并且可能会(也可能不会)中止执行(终止与非终止错误)。
  • try/catch不会捕获非终止错误,只会终止错误。尽管您可以预先设置$ErrorActionPreference = 'Stop'来将非终止错误升级为终止错误,但是在接收到第一条stderr行时,将终止程序(在ISE中)的执行。


  • 如果将PowerShell的使用范围限制为:,您可以 避免此问题
  • 一个终端(控制台),包括即将推出的Windows Terminal
  • Visual Studio CodePowerShell extension ;该跨平台编辑器(IDE)旨在取代obsolescent Windows PowerShell ISE

  • 这些环境的行为符合您的预期:
  • stderr(标准错误)输出默认传递给显示器
  • stderr行的打印与常规行一样。

  • 笔记:
  • 在远程作业和后台作业的上下文中,stderr输出仍将发送到PowerShell的错误流
  • 通过将2> 与外部程序一起使用,还存在其他,独立于主机的问题。

  • 有关所有问题的全面概述,请参见this answer

    关于git - 从外部命令向stderr写入时不要抛出PowerShell异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59366288/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com