Powershell эквивалент bash ampersand (&) для разветвления / запуска фоновых процессов - PullRequest
130 голосов
/ 09 октября 2008

В bash амперсанд (&) можно использовать для запуска команды в фоновом режиме и возврата интерактивного элемента управления пользователю до завершения выполнения команды. Есть ли эквивалентный способ сделать это в Powershell?

Пример использования в bash:

 sleep 30 &

Ответы [ 7 ]

107 голосов
/ 05 декабря 2012

Пока команда является исполняемым файлом или файлом, с которым связан исполняемый файл, используйте Start-Process (доступно из v2):

Start-Process -NoNewWindow ping google.com

Вы также можете добавить это как функцию в свой профиль:

function bg() {Start-Process -NoNewWindow @args}

и тогда вызов становится:

bg ping google.com

На мой взгляд, Start-Job - это избыточное решение для простого варианта использования процесса в фоновом режиме:

  1. Start-Job не имеет доступа к существующей области (поскольку он выполняется в отдельном сеансе). Вы не можете выполнить "Start-Job {notepad $ myfile}"
  2. Start-Job не сохраняет текущий каталог (потому что он запускается в отдельном сеансе). Вы не можете выполнить "Start-Job {notepad myfile.txt}", где myfile.txt находится в текущем каталоге.
  3. Выход не отображается автоматически. Вам нужно запустить Receive-Job с идентификатором задания в качестве параметра.

ПРИМЕЧАНИЕ. Что касается вашего первоначального примера, «bg sleep 30» не будет работать, потому что sleep - это командлет Powershell. Start-Process работает только тогда, когда вы фактически разветвляете процесс.

37 голосов
/ 09 октября 2008

Есть несколько ответов на этот вопрос.

  1. Вы не можете легко сделать это в версии 1
  2. Версия 2 (теперь в Community Tech Preview 2) имеет эту функцию, она называется Job (ранее PSJob). Узнайте больше об этом здесь или здесь .
  3. Вы действительно можете сделать это трудный путь в v1, не стесняйтесь, но я никогда не беспокоился.
19 голосов
/ 07 июля 2012

Похоже, что блок сценария, переданный в Start-Job, не выполняется с тем же текущим каталогом, что и команда Start-Job, поэтому при необходимости обязательно укажите полный путь.

Например:

Start-Job { C:\absolute\path\to\command.exe --afileparameter C:\absolute\path\to\file.txt }
19 голосов
/ 23 июня 2011
ps2> start-job {start-sleep 20}

Я еще не понял, как получить стандартный вывод в режиме реального времени. Для запуска задания требуется опросить стандартный вывод с помощью get-job

обновление: я не мог начать работу, чтобы легко делать то, что я хочу, в основном это оператор bash &. вот мой лучший взлом на данный момент

PS> notepad $profile #edit init script -- added these lines
function beep { write-host `a }
function ajp { start powershell {ant java-platform|out-null;beep} } #new window, stderr only, beep when done
function acjp { start powershell {ant clean java-platform|out-null;beep} }
PS> . $profile #re-load profile script
PS> ajp
12 голосов
/ 09 ноября 2016

Вы можете использовать командлеты PowerShell для достижения своих целей.

В PowerShell доступно 6 командлетов, связанных с заданиями.

  • Get-Job
    • Получает фоновые задания Windows PowerShell, которые выполняются в текущем сеансе
  • Receive-Job
    • Получает результаты фоновых заданий Windows PowerShell в текущем сеансе
  • Remove-Job
    • Удаляет фоновое задание Windows PowerShell
  • Start-Job
    • Запуск фонового задания Windows PowerShell
  • Stop-Job
    • Останавливает фоновое задание Windows PowerShell
  • Wait-Job
    • Подавляет командную строку до тех пор, пока одно или все фоновые задания Windows PowerShell, запущенные в сеансе, не будут завершены

Если интересно, вы можете скачать образец Как создать фоновое задание в PowerShell

8 голосов
/ 22 декабря 2018

В PowerShell Core 6.0 вы можете написать & в конце команды, и это будет эквивалентно запуску вашего конвейера в фоновом режиме в текущем рабочем каталоге .

Это не эквивалентно & в bash, это просто более приятный синтаксис для текущей функции PowerShell jobs . Он возвращает объект задания, поэтому вы можете использовать все остальные команды, которые вы использовали бы для заданий. Например Receive-Job:

C:\utils> ping google.com &

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
35     Job35           BackgroundJob   Running       True            localhost            Microsoft.PowerShell.M...


C:\utils> Receive-Job 35

Pinging google.com [172.217.16.14] with 32 bytes of data:
Reply from 172.217.16.14: bytes=32 time=11ms TTL=55
Reply from 172.217.16.14: bytes=32 time=11ms TTL=55
Reply from 172.217.16.14: bytes=32 time=10ms TTL=55
Reply from 172.217.16.14: bytes=32 time=10ms TTL=55

Ping statistics for 172.217.16.14:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 10ms, Maximum = 11ms, Average = 10ms
C:\utils>

Если вы хотите выполнить несколько операторов в фоновом режиме, вы можете объединить & оператор вызова , { } блок сценария и этот новый & оператор фона как здесь:

& { cd .\SomeDir\; .\SomeLongRunningOperation.bat; cd ..; } &

Вот еще немного информации со страниц документации:

из Что нового в PowerShell Core 6.0 :

Поддержка фоновой обработки трубопроводов с амперсандом (&) (# 3360)

Если поставить & в конце конвейера, конвейер будет запущен как задание PowerShell. Когда конвейер находится на заднем плане, возвращается объект задания. Когда конвейер запускается как задание, все стандартные командлеты *-Job могут использоваться для управления заданием. Переменные (игнорирующие переменные, специфичные для процесса), используемые в конвейере, автоматически копируются в задание, поэтому Copy-Item $foo $bar & просто работает. Задание также запускается в текущем каталоге вместо домашнего каталога пользователя. Для получения дополнительной информации о заданиях PowerShell см. about_Jobs .

из about_operators / Ampersand background operator & :

Фоновый оператор амперсанда &

Запускает конвейер перед ним в задании PowerShell. Фоновый оператор амперсанда действует аналогично «оператору амперсанда» в UNIX, который классно запускает команду перед ним как фоновый процесс. Фоновый оператор амперсанда построен на основе заданий PowerShell, поэтому он обладает многими функциональными возможностями Start-Job. Следующая команда содержит основные сведения об использовании фонового оператора амперсанда.

Get-Process -Name pwsh &

Это функционально эквивалентно следующему использованию Start-Job.

Start-Job -ScriptBlock {Get-Process -Name pwsh}

Поскольку это функционально эквивалентно использованию Start-Job, фоновый оператор амперсанда возвращает объект Job, такой же как Start-Job does. Это означает, что вы можете использовать Receive-Job и Remove-Job так же, как если бы вы использовали Start-Job для запуска задания.

$job = Get-Process -Name pwsh &
Receive-Job $job

выход

NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
------    -----      -----     ------      --  -- -----------
    0     0.00     221.16      25.90    6988 988 pwsh
    0     0.00     140.12      29.87   14845 845 pwsh
    0     0.00      85.51       0.91   19639 988 pwsh


$job = Get-Process -Name pwsh &
Remove-Job $job

Подробнее о заданиях PowerShell см. about_Jobs .

0 голосов
/ 09 октября 2008

Я успешно использовал описанное здесь решение http://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!130.entry в PowerShell v1.0. Это определенно будет проще в PowerShell v2.0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...