在 Windows PowerShell 中有条件地执行进程(例如 Bash 中的 && 和 || 运算符)

Posted

技术标签:

【中文标题】在 Windows PowerShell 中有条件地执行进程(例如 Bash 中的 && 和 || 运算符)【英文标题】:Execute process conditionally in Windows PowerShell (e.g. the && and || operators in Bash) 【发布时间】:2009-12-16 20:00:25 【问题描述】:

我想知道是否有人知道根据前一个程序的退出成功/失败有条件地执行程序的方法。如果 program1 在没有测试 LATEXITCODE 变量的情况下成功退出,我有什么办法可以在 program1 之后立即执行 program2?我尝试了 -band 和 -and 运算符无济于事,尽管我觉得它们无论如何都行不通,最好的替代品是分号和 if 语句的组合。我的意思是,当谈到在 Linux 上从源代码自动构建一个包时,&& 运算符是不可战胜的:

# Configure a package, compile it and install it
./configure && make && sudo make install

假设我实际上可以在 PowerShell 中使用相同的构建系统,PowerShell 将要求我执行以下操作:

# Configure a package, compile it and install it
.\configure ; if ($LASTEXITCODE -eq 0)  make ; if ($LASTEXITCODE -eq 0)  sudo make install  

当然,我可以使用多行,将其保存在一个文件中并执行脚本,但我的想法是让它简洁(节省击键)。也许这只是 PowerShell 和 Bash(甚至是支持 && 运算符的内置 Windows 命令提示符)之​​间的区别,我需要适应,但如果有更简洁的方法,我很想知道。

【问题讨论】:

对 Bash 风格的 &&|| 成为 PowerShell 的一部分感兴趣的人:请为 here 的功能投票。 在这里投票:GitHub 和这里:UserVoice 【参考方案1】:

您可以创建一个函数来执行此操作,但据我所知没有直接的方法。

function run-conditionally($commands) 
   $ranAll = $false
   foreach($command in $commands) 
      invoke-command $command
      if ($LASTEXITCODE -ne 0) 
          $ranAll = $false
          break; 
      
      $ranAll = $true
   

   Write-Host "Finished: $ranAll"

   return $ranAll

然后调用它类似于

run-conditionally(@(".\configure","make","sudo make install"))

如果没有方便的 powershell 环境,这可能会出现一些错误。

【讨论】:

我会对其进行调整以使其工作(需要 Invoke-Expression,因为 Invoke-Command 显然不能按应有的方式工作......或其他东西),但这绝对是有用的。谢谢您的帮助。非常感谢。 使用$LASTEXITCODE的问题是它只在PowerShell执行控制台EXE时设置。使用$? 可能会更好。 您可以为该函数设置别名以使其更易于调用。 @Orion Edwards,它有什么难看的? @Keith Hill,好点,我使用 $LastExitCode 不正确。 不是函数本身,而是调用它。当然你可以理解run-conditionally(@("a", "b"))a && b 丑:-)【参考方案2】:

我也因为缺少 && 而受到伤害,所以根据 GrayWizardX 的回答(不能按原样工作)编写了以下简单脚本:

foreach( $command in $args )

  $error.clear()
  invoke-command $command
  if ($error)  break; 

如果您将它保存为 rc.ps1(用于“有条件地运行”)在路径中的目录中,您可以像这样使用它:

rc .\configure make make install

使用脚本块(大括号)作为参数而不是字符串意味着您可以在输入命令时使用制表符完成,这样会更好。这个脚本几乎和 && 一样好,并且有效。

【讨论】:

此外,将第四行更改为 if ($?) break; 会使脚本的行为类似于 ||,以防不明显。 清除 $Error 集合不是一个好主意;测试$? 可以(if ($?) break 用于&&if (-not $?) break 用于||)。要使用Invoke-Command,您必须传递一个脚本块,所以最好这样输入$args 参数:[scriptblock[]] $args。此外,为防止副作用,请使用 Invoke-Command -NoNewScope - 或简单地使用 . 运算符。

以上是关于在 Windows PowerShell 中有条件地执行进程(例如 Bash 中的 && 和 || 运算符)的主要内容,如果未能解决你的问题,请参考以下文章

PowerShell 批量部署windows_exporter到所有Windows主机

PowerShell 批量创建用户用户组到所有Windows系统

PowerShell 批量创建用户用户组到所有Windows系统

PowerShell 批量创建用户用户组到所有Windows系统

Powershell简介

PowerShell 批量部署VMware-tools到所有Windows主机