【问题标题】:PS7.1 - How do you use pipeline chaining with custom functions?PS7.1 - 你如何使用带有自定义函数的流水线链接?
【发布时间】:2020-06-19 19:58:19
【问题描述】:

根据文档,PS 7 引入了诸如||&& 等流水线链接运算符。 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pipeline_chain_operators?view=powershell-7

您应该能够进行 C# 风格的短路操作,例如:

Write-Error 'Bad' && Write-Output 'Second'

上面的例子有效。并且文档说管道链接操作员使用两个字段(不确定它是如何工作的):$?$LASTEXITCODE

如何将这些应用到我自己的函数中?

例如:

function yes() { 
  echo 'called yes'
  return $True 
}
function no() { 
  echo 'called no'
  return $False 
}

我觉得我应该能够运行以下no && yes 并看到以下输出

不叫

错误

但我看到了

不叫

错误

是的

是的

那么,我该如何开发函数以使用流水线链接和短路呢?

编辑:我现在唯一能想到的构造一个自定义函数来短路&& 的唯一方法是使其成为throw,但这在一般情况下似乎不太有用。

【问题讨论】:

    标签: powershell powershell-7.0


    【解决方案1】:

    &&|| 仅对命令的成功状态 进行操作,如automatic $? variable(如您所说)所反映的那样 - 这是与命令输出(返回)无关。

    除非采取明确的行动,否则函数和脚本会将$? 报告为$true;也就是说,即使脚本/函数内部使用的命令失败,当脚本/函数退出时,$? 仍然是$true

    不幸的是,从 PowerShell 7.0 开始,函数无法直接将 $? 设置为 $false,尽管计划是添加这样的一项功能 - 请参阅 this GitHub isssue

    脚本 中,使用带有非零退出代码的 exit 是有效的,但是(这会导致 $LASTEXITCODE 反映退出代码和 PowerShell 引擎如果退出代码非零,则将 $? 设置为 $false - 这也是调用外部程序时的工作方式。


    目前,函数只有以下次优解决方法;这是次优的,因为它总是发出错误消息

    function no { 
      # Make the function an advanced one, so that $PSCmdlet.WriteError()
      # can be called.
      [CmdletBinding()]
      param()
    
      # Call $PSCmdlet.WriteError() with a dummy error, which
      # sets $? to $false in the caller's scope.
      # By default, this dummy error prints and is recorded in the $Error
      # collection; you can use -ErrorAction Ignore on invocation to suppress
      # that.
      $PSCmdlet.WriteError(
       [System.Management.Automation.ErrorRecord]::new(
         [exception]::new(), # the underlying exception
         'dummy',            # the error ID
         'NotSpecified',     # the error category
         $null)              # the object the error relates to
      ) 
    }
    

    函数no 现在将$? 设置为false,这会触发|| 分支; -EA Ignore (-ErrorAction Ignore) 用于消除虚拟错误。

    PS> no -EA Ignore || 'no!'
    no!
    

    【讨论】:

    • 哇。好的。可惜现在还不支持。感谢您提供令人难以置信的完整答案
    • 很高兴听到它有帮助,@Kir;我的荣幸。同意现在是支持这一点的时候了。 &&|| 是从类似 POSIX 的 shell 中借来的,不太适合原生 PowerShell 命令。 $? 总是有其怪癖,使其实用性受到质疑,但现在,有了 &&||,能够有意设置它很重要。 linked GitHub issue 还显示了 &&|| 在概念上如何与 PowerShell 的 Test-* cmdlet 不一致。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2022-10-25
    相关资源
    最近更新 更多