如何告诉PowerShell在开始下一个命令之前等待每个命令结束?

Joh*_*Mee 198 powershell execution wait

我有一个PowerShell 1.0脚本来打开一堆应用程序.第一个是虚拟机,其他是开发应用程序.我希望虚拟机在其他应用程序打开之前完成启动.

在bash我可以说 "cmd1 && cmd2"

这就是我所拥有的......

C:\Applications\VirtualBox\vboxmanage startvm superdooper
    &"C:\Applications\NetBeans 6.5\bin\netbeans.exe"
Run Code Online (Sandbox Code Playgroud)

Kei*_*ill 340

通常,对于内部命令,PowerShell会在开始下一个命令之前等待.此规则的一个例外是基于外部Windows子系统的EXE.第一个技巧是管道Out-Null如此:

Notepad.exe | Out-Null
Run Code Online (Sandbox Code Playgroud)

PowerShell将等待Notepad.exe进程退出,然后再继续.从阅读代码开始,这很有趣,但有点微妙.您还可以使用-Wait参数启动进程:

Start-Process <path to exe> -NoNewWindow -Wait
Run Code Online (Sandbox Code Playgroud)

如果您使用的是PowerShell社区扩展版本,那么它是:

$proc = Start-Process <path to exe> -NoWindow
$proc.WaitForExit()
Run Code Online (Sandbox Code Playgroud)

PowerShell 2.0中的另一个选项是使用后台作业:

$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job
Run Code Online (Sandbox Code Playgroud)

  • 很棒,`| out-null`就是我所需要的.尝试使用`Start-Job`但是因为我将函数的结果作为参数传递,它对我有点滑动,所以我无法使用最后的建议...... (6认同)
  • 作为旁注,如果需要使用`-ArgumentList`传递多个参数,请用逗号分隔它们,如`-ArgumentList/D = test,/ S`. (6认同)
  • 我的错。Start-Process -Wait 效果很好,但现在我发现这不是我想要的……我实际上是想等到 vm 完成启动。我想这会很艰难。我想我必须为此找到一个新线程。谢谢但是。 (3认同)

Nat*_*ley 45

除了使用之外Start-Process -Wait,管道输出可执行文件将使Powershell等待.根据不同的需要,我通常会管Out-Null,Out-Default,Out-StringOut-String -Stream.是一些其他输出选项的长列表.

# Saving output as a string to a variable.
$output = ping.exe example.com | Out-String

# Filtering the output.
ping stackoverflow.com | where { $_ -match '^reply' }

# Using Start-Process affords the most control.
Start-Process -Wait SomeExecutable.com
Run Code Online (Sandbox Code Playgroud)

我确实想念你引用的CMD/Bash样式运算符(&,&&,||).看来我们必须对Powershell更加冗长.


小智 11

只需使用"等待过程":

"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir
Run Code Online (Sandbox Code Playgroud)

工作完成了

  • 它不适用于 PowerShell 7.1.4(在 Windows 10 上)。 (2认同)

San*_*man 7

如果你使用 Start-Process <path to exe> -NoNewWindow -Wait

您也可以使用该-PassThru选项来回显输出.

  • 请注意,“-PassThru”不会回显_output_(根据定义,非控制台应用程序不会产生控制台输出),它会输出一个代表新启动进程的“System.Diagnostics.Process”实例,因此您可以检查其属性并等待其稍后退出。 (2认同)

小智 6

有些程序无法很好地处理输出流,使用管道Out-Null可能无法阻止它.
并且Start-Process需要-ArgumentList交换机传递参数,不太方便.
还有另一种方法.

$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)
Run Code Online (Sandbox Code Playgroud)

  • 多个参数如何在该调用中工作?它们是如何分隔的?如何处理各种嵌套字符串转义?泰! (2认同)

mse*_*any 3

这个问题很久以前就被问到了,但由于这里的答案是一种参考,我可能会提到最新的用法。通过当前的实现PowerShell(截至7.2 LTS撰写本文时),您可以&&像在Bash.

根据左侧管道的成功有条件地执行右侧管道。

   # If Get-Process successfully finds a process called notepad,
   # Stop-Process -Name notepad is called
   Get-Process notepad && Stop-Process -Name notepad
Run Code Online (Sandbox Code Playgroud)

有关文档的更多信息