2

根据文档,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并看到以下输出

叫不

错误的

但相反,我看到

叫不

错误的

叫是

真的

那么,我如何以可以使用流水线链接和短路的方式开发功能呢?

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

4

1 回答 1

1

&&||仅对命令的成功状态进行操作,这反映在自动$?变量(如您所说)中 - 这与命令输出(返回)的内容无关。

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

不幸的是,从 PowerShell 7.0 开始,没有直接方法可以将函数直接设置$?$false,尽管计划是添加这样的功能 - 请参阅此 GitHub 问题

但是,在脚本中,使用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!
于 2020-06-19T11:27:36.617 回答