echo $怎么样?工作?

Viv*_*Dev 3 error-handling powershell exit-code automatic-variable

我正在编写一些PowerShell脚本来进行一些构建自动化.我发现这里回声$?返回true或false,具体取决于之前的语句.我刚刚发现echo是Write-Output的别名.写主机$?也有效.但我还不清楚这是多少钱?作品.有人可以说一些关于这个的话.正在搜索echo $?在网上并没有给我太多.

mkl*_*nt0 5

通过更详细的信息补充Martin Brandl的有用答案:

TL;博士

  • 自动变量$?(请参阅参考资料Get-Help about_Automatic Variables)包含一个布尔值,该布尔值反映最近的语句中是否发生任何非终止错误.

    • 由于$?每个声明之后设置,您必须在感兴趣的声明之后立即检查,或保存它以供以后检查.
    • 请参阅下文,了解可能违反直觉的行为.
  • 自动变量通过记录最近执行的外部命令行实用程序(例如)的特定退出代码补充这一点.$LASTEXITCODE findstr

    • $LASTEXITCODE补充$?$?只反映抽象的外部工具的成功或失败-退出代码0映射到$True,任何非零退出代码$False-而$LASTEXITCODE包含实际的退出代码.
    • 由于$LASTEXITCODE仅为外部命令行实用程序设置,因此其值通常保持有效的时间长于每个语句$?后设置的值.

关于如何设置有许多细微之处$?,其精确地表示其值:

  • $?只反映了非终止错误的发生,因为(更少见的)终止错误默认终止当前命令行/脚本的执行,并且处理它们需要使用try / catch(首选)或trap(参见Get-Help about_Try_Catch_FinallyGet-Help about_Trap).

  • 除非明确忽略(使用公共-ErrorAction Ignorecmdlet参数),否则所有非终止错误(以及捕获的终止错误)将按$Error相反的时间顺序收集在自动收集中; 也就是说,element $Error[0]包含最新的错误.

  • 对于传递多个输入对象的命令,$?包含$False告诉您至少一个输入对象的处理失败.换句话说:输入对象的任何子集都可能发生错误,包括所有输入对象.

    • 要确定确切的错误计数和有问题的输入对象,您必须检查该$Error集合.
  • 随着非远程间接执行的cmdlet到你传递一个目标要执行的命令-例如Invoke-Expression,Start-ProcessStart-JobInvoke-Command 没有-ComputerName参数(不涉及远程-见下文) - $?只反映是否达到了目标命令可以被调用的原则,无论该命令是否报告错误.

    • 一个简单的例子:Invoke-Expression '1 / 0'设置$?$True(!),因为Invoke-Expression能够解析和调用表达式,即使表达式本身失败了.
    • 同样,检查$Error集合会告诉您目标命令报告的错误和错误.
  • 随着远程(总是间接执行)的cmdlet,尤其是与Invoke-Command-ComputerName参数(这是典型的),但也有含蓄远程小命令,$? 反映是否目标命令报告的任何错误.

    • 一个简单的例子(必须从运行高架控制台和假设本地机器已被设置用于在远程)
      Invoke-Command -ComputerName . { 1 / 0 },因为远程参与,确实将$?$False来反映目标的命令失败1 / 0.
      请注意,即使本地计算机(.)是目标,使用-ComputerName总是使用远程处理.

    • 请注意,根据设计,远程处理报告通常会将远程发生的错误作为终止错误报告,可能是因为一台目标计算机上的正常终止错误不会中止所有其他目标计算机上的处理.


  • DO反映错误的命令示例$?:

    # Invoking a non-existing cmdlet or utility directly.
    NoSuchCmd
    
    # Ditto, via call operator &.
    # Note, however, that using a *script block* with & behaves differently - see below.
    & 'NoSuchCmd'
    
    # Invoking a cmdlet with invalid parameter syntax.
    Get-ChildItem -NoSuchParameter
    
    # Invoking a cmdlet with parameter values that cause a (non-terminating) runtime error.
    Get-ChildItem NoSuchFile
    
    # Invoking an external utility that reports a nonzero exit code. 
    findstr -nosuchoptions
    # The specific exit code is recorded in $LASTEXITCODE, 
    # until the next external utility is called.
    
    # Runtime exceptions
    1 / 0
    
    # A cmdlet that uses remoting:
    # (Must be run from an elevated session, and the local machine must
    # be configured for remoting first - run `winrm quickconfig`).
    # Note that remoting would NOT be involved WITHOUT the -ComputerName parameter, 
    # in which case `$?` would only reflect whether the script block could be
    # _invoked_, irrespective of whether its command(s) then fail or not.
    Invoke-Command -ComputerName . { 1 / 0 }
    
    # A .NET method that throws an exception.
    # Note: Outside of a `try/catch` handler, this is a non-terminating error.
    # Inside a `try/catch` handler, .NET exceptions are treated as terminating
    # and trigger the `catch` block.
    [System.IO.Path]::IsPathRooted('>')
    
    Run Code Online (Sandbox Code Playgroud)
  • 不反映错误的命令示例$?:

    <#
      Non-remoting indirect execution cmdlets:
    
      $? reflects only whether the specified command could be 
      *invoked*, irrespective of whether the command itself then failed or not.
    
      In other words: $? is only $False if the specified command could not even be
      executed, such as due to invalid parameter syntax, an ill-formed target
      command, or a missing target executable. 
    
    #>
    
    # Invoking a command stored in a script block.
    & { 1 / 0 }
    
    # Invoking an expression stored in a string.
    Invoke-Expression '1 / 0'
    
    # Starting a background job.
    Start-Job { 1/ 0 }
    
    # The *non-remoting* form of Invoke-Command (WITHOUT -ComputerName).
    Invoke-Command { 1 / 0 }
    
    Run Code Online (Sandbox Code Playgroud)