什么是PowerShell等同于Bash&&和||运营商?

时间:2010-03-10 12:04:26

标签: bash powershell language-comparisons

在Bash中,我可以轻松地执行类似

的操作
command1 && command2 || command3

表示运行command1,如果command1成功运行command2,并且command1无法运行command3。

PowerShell中的等价物是什么?

4 个答案:

答案 0 :(得分:21)

首次提出问题多年后,让我总结一下PowerShell v5.1 的事态:

  • Bash / cmd' &&||控制运营商没有PowerShell等效,自此以后无法在PowerShell中定义自定义运算符,没有良好的解决方法

    • 使用单独的命令(在单独的行上或用;分隔),并通过自动变量$?显式测试每个命令的成功状态,例如:
      command1 -arg1 -arg2; if ($?) { command2 -arg1 } # equivalent of &&
      command1 -arg1 -arg2; if (-not $?) { command2 -arg1 } # equivalent of ||

    • 请参阅下文,了解为什么PowerShell -and-or通常解决方案。

  • 有一段时间有talk about adding them ,但它似乎从未成为榜单的首位。

    • 现在PowerShell已经开源了,一个issue has been opened on GitHub
    • 令牌&&||目前保留供将来在PowerShell中使用,因此希望能够实现与Bash中相同的语法。
      (自PSv5.1起,尝试1 && 1之类的内容会产生错误消息The token '&&' is not a valid statement separator in this version.

为什么PowerShell的-and-or无法替代&&||

Bash 的控件操作符&&(短路逻辑AND)和||(短路逻辑OR)隐式检查成功命令的状态由退出代码而不干扰其输出流 ; e.g:

ls / nosuchfile && echo 'ok'

无论ls输出 - stdout输出(/中的文件)和stderr输出(尝试访问不存在的文件nosuchfile的错误消息) - 是< em>传递,但&&检查ls命令的(不可见)退出代码以确定echo命令 - RHS应该执行&&控制运算符。

在这种情况下,

ls报告退出代码1,表示失败 - 因为文件nosuchfile不存在 - 所以{{1 }}判断&& 失败,并通过应用短路来决定不需要执行ls命令。
请注意,退出代码echo标志着0cmd.exe世界的成功,而任何非零退出代码都表示失败。

换句话说: Bash&#39; bash&&完全独立于命令操作&#39; 输出,仅对命令的成功状态执行操作。

相比之下,PowerShell的||-and只会对命令进行操作。标准(成功)输出消耗然后仅输出操作的布尔结果; e.g:

-or

以上:

  • 使用并使用 成功(标准)输出 - (Get-ChildItem \, nosuchfile) -and 'ok' 的列表 - 并将其解释为布尔值;在布尔上下文中,非空输入集合被视为\,因此,如果至少有一个条目,则表达式的计算结果为$true

    • 但是,由不存在的文件$true 导致的错误信息是传递的,因为错误会发送到单独的流。
  • 鉴于nosuchfile返回非空成功输出,LHS评估为Get-ChildItem \, nosuchfile,因此$true也评估RHS,-and,但是, ,使用其输出并将其解释为布尔值,作为非空字符串,也计算为'ok'

  • 因此,$true表达式的总体结果为-and,这是(唯一成功的)输出

净效果是:

  • 评估过程中$true表达式两侧的成功输出 消耗因此有效隐藏

  • 表达式的唯一(成功)输出是其布尔结果,在这种情况下为-and(在{0}中呈现为$true英语系统中的终端)。

答案 1 :(得分:9)

Bash必须做的是在传递给逻辑运算符时将命令的退出代码隐式地转换为布尔值。 PowerShell不会这样做 - 但可以使用一个函数来包装命令并创建相同的行为:

> function Get-ExitBoolean($cmd) { & $cmd | Out-Null; $? }

$? is a bool containing the success of the last exit code

给出两个批处理文件:

#pass.cmd
exit

#fail.cmd
exit /b 200

......行为可以测试:

> if (Get-ExitBoolean .\pass.cmd) { write pass } else { write fail }
pass
> if (Get-ExitBoolean .\fail.cmd) { write pass } else { write fail }
fail

逻辑运算符的评估方式与Bash相同。首先,设置别名:

> Set-Alias geb Get-ExitBoolean

测试:

> (geb .\pass.cmd) -and (geb .\fail.cmd)
False
> (geb .\fail.cmd) -and (geb .\pass.cmd)
False
> (geb .\pass.cmd) -and (geb .\pass.cmd)
True
> (geb .\pass.cmd) -or (geb .\fail.cmd)
True

答案 2 :(得分:-1)

我们可以使用try catch finally方法而不是使用&amp;&amp; powershell中的方法。

try {hostname} catch {echo err} finally {ipconfig /all | findstr bios}

答案 3 :(得分:-1)

您可以执行类似的操作,在其中使用[void]隐藏布尔输出,并且只会产生副作用。在这种情况下,如果$ a或$ b为空,则$ c被分配给$ result。赋值可以是表达式。

$a = ''
$b = ''
$c = 'hi'

[void](
  ($result = $a) -or
  ($result = $b) -or
  ($result = $c))

$result

输出

hi