在Bash中,我可以轻松地执行类似
的操作command1 && command2 || command3
表示运行command1,如果command1成功运行command2,并且command1无法运行command3。
PowerShell中的等价物是什么?
答案 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中使用,因此希望能够实现与Bash中相同的语法。1 && 1
之类的内容会产生错误消息The token '&&' is not a valid statement separator in this version.
)-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
标志着0
和cmd.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