Запустите docker в фоновом режиме под Powershell - PullRequest
1 голос
/ 30 марта 2020

Простой вопрос, я хочу запустить команду docker в фоновом режиме.
(Фактически, выполнение любой команды с параметрами командной строки в Powershell - это мой реальный вопрос, но docker - это простой конкретный вопрос)

У меня есть команда

docker run -ti --rm -e DISPLAY=$DISPLAY firefox

, которая отлично работает под Powershell, но блокируется.

Я хочу запустить эквивалентный метод "&", как в * nix:

docker run -ti --rm -e DISPLAY=$DISPLAY firefox &

Я пробовал

, но ни один из них не работает для меня:

> ping google.com &
At line:1 char:17
+ ping google.com &
+                 ~
The ampersand (&) character is not allowed.

> Start-Process "C:\Program Files\Docker\Docker\resources\bin\docker.exe" run -ti --rm -e DISPLAY=$DISPLAY firefox
Start-Process : Parameter cannot be processed because the parameter name 'e' is ambiguous. Possible
matches include: -ErrorAction -ErrorVariable.
At line:1 char:86
+ ... Files\Docker\Docker\resources\bin\docker.exe" run -ti --rm -e DISPLAY ...
+                                                                ~~
    + CategoryInfo          : InvalidArgument: (:) [Start-Process], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.StartProcessCommand

Попытка обернуть всю команду в Start-Process { ... } тоже не работает.

[ОБНОВЛЕНИЕ / Сводка]

Принятые ответы работают (после того как я удалил "-ti" из командной строки), как сказал @nischay goyal, «пожалуйста, не используйте -it, так как он открывает терминал и блокирует его.» . Я получил ошибку:

the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'
    + CategoryInfo          : NotSpecified: (the input devic...d with 'winpty':String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
    + PSComputerName        : localhost
  • Так что Start-Job может не подходит для общего назначения "&", например, если Я хочу начать bash & таким образом.

  • Однако Start-Process работает после передачи всех остальных параметров командной строки docker параметру -ArgumentList в виде одной строки.

  • И, конечно, как говорят все люди из лагеря докеров / Linux, используйте -d.

В общем, есть много способов решить проблему. Выберите тот, который подходит вам.

Ответы [ 4 ]

1 голос
/ 30 марта 2020

Используйте Start-Job для запуска команды в фоновом режиме в PowerShell.

В PowerShell [Core] 6+ вы также можете поместить & в конце вашей команды, так же, как в POSIX-подобных оболочках, таких как Bash.

. В обоих случаях возвращается объект задания (System.Management.Automation.PSRemotingJob), которым вы можете управлять с помощью различных *-Job командлеты - см. about_Jobs .

Задания в PowerShell похожи на задания в оболочках, подобных POSIX (например, Bash) , но есть некоторые фундаментальные различия , в частности интерактивные интерактивные команды в фоновом режиме - см. этот комментарий на GitHub .

Фоновые задания используют дочерний процесс , который запускает скрытый экземпляр PowerShell в фоновом режиме, который является медленным и ресурсоемким.

Поэтому считают резьба на основе Start-ThreadJob командлет как более быстрая и более легкая альтернатива - см. это ответ .

Синтаксис, который работает также в версиях PowerShell ниже 6, с Start-Job:

# Preferable alternative: Start-ThreadJob
$job = Start-Job { docker run --rm -e DISPLAY=$using:DISPLAY firefox }

Примечание: -ti было удален, поскольку, как указывает Nischay Goyal , он откроет сеанс интерактивной оболочки , что означает, что вызов не вернется, пока этот сеанс не будет закрыт вручную. Однако, не то, что Start-Job обычно не поддерживает запуск интерактивных программ в фоновом режиме, как объяснено здесь .

Обратите внимание на необходимость обращения к переменной $DISPLAY в область действия вызывающего абонента через спецификатор области действия $using: - см. about_Remote_Variables .

Предупреждение: в версиях PowerShell вплоть до 6.x фоновые задания, запускаемые таким образом, использовали fixed рабочий каталог, не связанный с вызывающим абонентом - см. этот ответ .

Альтернатива PowerShell [Core] 6+: размещение & в конце команды:

$job = docker run --rm -e DISPLAY=$DISPLAY firefox &

Обратите внимание, что не нужен спецификатор области $using: с этим синтаксисом, и даже в PowerShell 6.x задание видит тот же рабочий каталог, что и вызывающая сторона.

Обратите внимание, что нет аналогичного краткого синтаксиса для создания thread заданий (эквивалент вызова Start-ThreadJob), но в PowerShell 7.0 , но его добавление является предметом запрос этой функции на GitHub .


Как уже говорилось, вы можете использовать различные другие командлеты *-Job для управления заданием после создания (они также управляют заданиями потока, созданными с помощью Start-ThreadJob); например, следующая команда синхронно ожидает завершения задания, печатает его вывод и затем удаляет задание.

$job | Receive-Job -Wait -AutoRemoveJob

Что касается того, что вы пытались :

Постпозиционное & в ping google.com & не работало, потому что вы работаете в Windows PowerShell (версии PowerShell до v5.1), тогда как для этого синтаксиса требуется PowerShell [ Core] версии 6 или выше.

Start-Process предназначен для запуска исполняемого файла асинхронно и в новом окне по умолчанию (на Windows).
Это в основном полезно для запуска GUI приложений (асинхронно) или запуска команд оболочки в новом окне консоли.

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

Причина, по которой ваш вызов не удался, заключается в том, что вы пытались передать сквозные аргументы напрямую в Start-Process вместо передачи их в -ArgumentList par ameter (в простейшем случае одной строкой).

1 голос
/ 30 марта 2020

Чтобы запустить контейнер docker в отдельном режиме, не используйте -it, поскольку он открывает терминал и блокирует его.

docker run --rm -e DISPLAY=$DISPLAY firefox

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

Start-Process -NoNewWindow ping google.com
1 голос
/ 30 марта 2020

Команда firefox не ожидает ввода в stdin и не нуждается в tty. Так что удалите -it. Затем добавьте -d, который обозначает отдельный режим, стандартный способ запуска демонов внутри docker или другие неинтерактивные команды.

docker run -d --rm -e DISPLAY=$DISPLAY firefox
0 голосов
/ 30 марта 2020

чтобы полностью выполнить команду в docker с docker в фоновом режиме, вы можете использовать:

docker run $YourOption $ImageDocker exec $yourCommand 

и не использовать опции -i -t, это открывает терминал

сделать что-то вроде

docker run --rm -e DISPLAY=$DISPLAY firefox exec "ping google.com"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...