Syntax powershell中的条件执行(&;&;和| |)
已经有一个问题解决了我的问题(),但有一点不同。我需要两个命令的输出。看,如果我只是跑:Syntax powershell中的条件执行(&;&;和| |),syntax,powershell,command-execution,Syntax,Powershell,Command Execution,已经有一个问题解决了我的问题(),但有一点不同。我需要两个命令的输出。看,如果我只是跑: (command1 -arg1 -arg2) -and (command2 -arg1) 我不会看到任何输出,但会看到stderr消息。正如所料,只需键入: command1 -arg1 -arg2 -and command2 -arg1 给出语法错误。2019:Powershell团队 试试这个: $(command -arg1 -arg2 | Out-Host;$?) -and $(command
(command1 -arg1 -arg2) -and (command2 -arg1)
我不会看到任何输出,但会看到stderr消息。正如所料,只需键入:
command1 -arg1 -arg2 -and command2 -arg1
给出语法错误。2019:Powershell团队 试试这个:
$(command -arg1 -arg2 | Out-Host;$?) -and $(command2 -arg1 | Out-Host;$?)
$()
是一个子表达式,允许您在一个管道中指定多个语句。然后执行命令并将管道输送到Out主机
,以便您可以看到它。下一条语句(子表达式的实际输出)应输出$?
,即最后一条命令的成功结果
$?
适用于本机命令(console exe),但对于cmdlet,它还有一些不足之处。也就是说,$?
似乎只在cmdlet遇到终止错误时返回$false
。似乎$?
至少需要三种状态(失败、成功和部分成功)。因此,如果您使用cmdlet,这会更好:
$(command -arg1 -arg2 -ev err | Out-Host;!$err) -and
$(command -arg1 -ev err | Out-Host;!$err)
这种打击仍然存在。也许这样更好:
function ExecuteUntilError([scriptblock[]]$Scriptblock)
{
foreach ($sb in $scriptblock)
{
$prevErr = $error[0]
. $sb
if ($error[0] -ne $prevErr) { break }
}
}
ExecuteUntilError {command -arg1 -arg2},{command2-arg1}
为了简化doThis | | exit 1非常有用的多步骤脚本,我使用以下方法:
function ProceedOrExit {
if ($?) { echo "Proceed.." } else { echo "Script FAILED! Exiting.."; exit 1 }
}
doThis; ProceedOrExit
doNext
# or for long doos
doThis
ProceedOrExit
doNext
稍长一点的路见下文
try {
hostname
if ($lastexitcode -eq 0) {
ipconfig /all | findstr /i bios
}
} catch {
echo err
} finally {}
更新:PowerShell[Core]7.0引入了&&
和|
支持-请参阅
Bash的/
cmd
的&
和|
控制操作符没有与Windows PowerShell等效的,而且由于无法定义自定义操作符,因此没有好的解决方法
- 基于| Out Host的解决方案是一个严重受限的解决方案,因为它只能向控制台(终端)发送正常的命令输出,从而防止输出通过管道发送或捕获到变量或文件中
在中查找背景信息。最简单的解决方案是使用
powershell command1 && powershell command2
在cmd外壳中。当然,您不能在.ps1脚本中使用此选项,因此存在此限制。Powershell 7 preview 5具有这些选项。 我不知道为什么在没有通知或解释的情况下删除了此项。 这将根据问题的要求给出两个命令的输出
echo 'hello' && echo 'there'
hello
there
echo 'hello' || echo 'there'
hello
Powershell 7.0发布后,支持
&&
和| |
如果第一次求值为false(失败),则短循环OR将仅执行第二个表达式。我怀疑OP只希望在第一个evals为true(成功)时执行第二个表达式这是一个短路-并且给了我们。任何对Bash风格
&&
和|
成为PowerShell的一部分感兴趣的人:请投票支持该功能。可能重复的注意事项:尽管这个问题同时提到了&
和|
,但是,正文——以及随后的答案——只关注&&
。2019年6月更新:PowerShell团队正在实施&&
和|
!在“谢谢你”,基思(顺便说一句,我使用PSCX,觉得它很棒,非常感谢!)。虽然它看起来很有用,但与UNIX管道相比有一个缺点。考虑下面的内容:<代码>命令1和命令2}命令< <代码>。我认为这是一种非常常见的模式。是的,与适当的&&和| | |支持相比,这是有点麻烦。因为(至少)PSv2,非终止错误会将$?
设置为$false
:例如,$null=Get Item\,nosuch;$代码>输出$false
。在终止错误的情况下,默认情况下命令行/脚本将完全中止;如果您尝试执行/捕捉
错误,$?
在捕捉
块中是$false
,或者如果捕捉
块为空,则紧接着;e、 例如,try{throw“terminating err”}catch{};$
ExecuteUntilError
功能很方便,但请更清楚地说明主机外挂解决方案的黑客攻击程度,假设它绕过了正常的成功输出流,因此阻止通过管道发送输出或将其捕获到变量或文件中。要解释您关于需要3$?
的声明,请说明:对于cmdlet,$?
只允许您区分“成功处理所有输入项”和处理至少一个(但可能是所有)输入项失败"; 换句话说:你无法区分部分失败和完全失败;解决方法是将输入计数与$Error.count
中的更改进行比较。不需要try
/catch
,因为它只用于终止错误,而外部实用程序(如主机名
、ipconfig
和findstr
无法触发这些错误。仅当您想知道外部实用程序设置的特定退出代码时,才需要检查$LASTEXITCODE
。
与本机cmdlet一样,抽象成功或失败会反映在$?
中。旁白:请。@FrancescoMantovani,没错,但是这里的&
不在powershell中,它在cmd shell中。我在这里的答案是使用cmd将两个powershell命令串在一起(都打印了完整的输出)。这是正确的答案。如果您正在认真使用powershell,请使用powershell预览巧克力套装。
New operators:
Ternary operator: a ? b : c
Pipeline chain operators: || and &&
Null coalescing operators: ?? and ??=