如何告诉 PowerShell 等待每个命令结束后再开始下一个命令?

问题描述 投票:0回答:10

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

在 bash 中我只能说

"cmd1 && cmd2"

这就是我所拥有的...

C:\Applications\VirtualBox\vboxmanage startvm superdooper
    &"C:\Applications\NetBeans 6.5\bin\netbeans.exe"
powershell wait execution
10个回答
470
投票

通常,对于内部命令,PowerShell 会在开始下一个命令之前等待。 此规则的一个例外是基于外部 Windows 子系统的 EXE。 第一个技巧是像这样管道化到

Out-Null

Notepad.exe | Out-Null

PowerShell 将等待 Notepad.exe 进程退出后再继续。 这很漂亮,但从阅读代码中发现有点微妙。 您还可以将

Start-Process
-Wait
参数一起使用:

Start-Process <path to exe> -NoNewWindow -Wait

如果您使用的是 PowerShell 社区扩展版本,则为:

$proc = Start-Process <path to exe> -NoNewWindow -PassThru
$proc.WaitForExit()

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

$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job

67
投票

除了使用

Start-Process -Wait
之外,通过管道传输可执行文件的输出将使 Powershell 等待。根据需要,我通常会通过管道传输到
Out-Null
Out-Default
Out-String
Out-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

我确实怀念您引用的 CMD/Bash 风格运算符(&、&&、||)。它 看来我们必须使用 Powershell 更详细


15
投票

只需使用“等待过程”:

"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir

工作完成了


11
投票

如果您使用

Start-Process <path to exe> -NoNewWindow -Wait

您还可以使用

-PassThru
选项来回显输出。


8
投票

有些程序不能很好地处理输出流,使用管道

Out-Null
可能不会阻止它。
而且
Start-Process
需要
-ArgumentList
开关来传递参数,不太方便。
还有另一种方法。

$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)

4
投票

这个问题很久以前就被问到了,但由于这里的答案是一种参考,我可能会提到最新的用法。使用

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

有关 文档

的更多信息

4
投票

包含选项

-NoNewWindow
会给我一个错误:
Start-Process : This command cannot be executed due to the error: Access is denied.

我让它工作的唯一方法是打电话:

Start-Process <path to exe> -Wait

4
投票

基于@Justin 和@Nathan Hartley 的回答:

& "my.exe" | Out-Null    #go nowhere    
& "my.exe" | Out-Default # go to default destination  (e.g. console)
& "my.exe" | Out-String  # return a string

管道会实时返回

& "my.exe" | %{    
   if ($_ -match 'OK')    
   { Write-Host $_ -f Green }    
   else if ($_ -match 'FAIL|ERROR')   
   { Write-Host $_ -f Red }   
   else    
   { Write-Host $_ }    
}

注意:如果执行的程序返回 0 退出代码以外的任何内容,则管道将无法工作。您可以强制它使用重定向运算符进行管道传输,例如

2>&1

& "my.exe" 2>&1 | Out-String

来源:

https://stackoverflow.com/a/7272390/254276

https://social.technet.microsoft.com/forums/windowsserver/en-US/b6691fba-0e92-4e9d-aec2-47f3d5a17419/start-process-and-redirect-output-to-powershell-window


2
投票

更进一步,你甚至可以即时解析

例如

& "my.exe" | %{
    if ($_ -match 'OK')
    { Write-Host $_ -f Green }
    else if ($_ -match 'FAIL|ERROR')
    { Write-Host $_ -f Red }
    else 
    { Write-Host $_ }
}

0
投票

cmd 总是有的。

cmd /c start /wait notepad

或者

notepad | out-host

这是另一个奇怪的事情。 即使第二个 powershell 退出,启动进程仍会等待记事本。 (“cmd /c start /wait powershell notepad”不会执行此操作。)因此,即使进程树中的任何内容在后台运行(NSIS 卸载程序在foldathome、notepad++、psychopy、ciscoamp、firefox、scratch 中执行此操作),它还在等待。

start-process -wait powershell notepad
© www.soinside.com 2019 - 2024. All rights reserved.