Как сказать PowerShell дождаться окончания каждой команды до начала следующего?
У меня есть PowerShell 1.0 script, чтобы просто открыть кучу приложений. Первая - это виртуальная машина, а другие - приложения для разработки. Я хочу, чтобы виртуальная машина завершила загрузку до открытия остальных приложений.
В bash я могу просто сказать "cmd1 && cmd2"
Это то, что у меня есть...
C:\Applications\VirtualBox\vboxmanage startvm superdooper
&"C:\Applications\NetBeans 6.5\bin\netbeans.exe"
Ответы
Ответ 1
Как правило, для внутренних команд PowerShell ждет перед началом следующей команды. Единственным исключением из этого правила является внешняя подсистема под управлением ОС Windows. Первый трюк состоит в том, чтобы выполнить конвейер до 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> -NoWindow
$proc.WaitForExit()
Другой вариант в PowerShell 2.0 - использовать фоновое задание:
$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job
Ответ 2
Кроме того, используя 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.
Ответ 3
Просто используйте "Wait-process":
"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir
выполняется
Ответ 4
Если вы используете Start-Process <path to exe> -NoNewWindow -Wait
Вы также можете использовать опцию -PassThru
для вывода эха.
Ответ 5
Некоторые программы не могут обрабатывать выходной поток очень хорошо, используя pipe to Out-Null
, возможно, не заблокировать его.
И Start-Process
нужен переключатель -ArgumentList
для передачи аргументов, что не так удобно.
Существует и другой подход.
$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)
Ответ 6
Включение опции -NoNewWindow
дает мне ошибку: Start-Process : This command cannot be executed due to the error: Access is denied.
Единственный способ заставить его работать:
Start-Process <path to exe> -Wait
Ответ 7
Принимая это дальше, вы можете даже разобрать на лету
например
& "my.exe" | %{
if ($_ -match 'OK')
{ Write-Host $_ -f Green }
else if ($_ -match 'FAIL|ERROR')
{ Write-Host $_ -f Red }
else
{ Write-Host $_ }
}