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 ??=