运行 docker 在 Powershell 后台
Run docker in background under Powershell
简单的问题,我想在后台执行运行 docker命令。
(实际上 运行 在 Powershell 下使用命令行参数执行任何命令是我真正的问题,但是 docker
是一个简单的具体问题)
我有一个命令
docker run -ti --rm -e DISPLAY=$DISPLAY firefox
运行在 Powershell 下没问题,但会阻塞。
我想运行使用 *nix:
下执行“&”的等效方法
docker run -ti --rm -e DISPLAY=$DISPLAY firefox &
我试过了
- Powershell equivalent of bash ampersand (&) for forking/running background processes
但都不适合我:
> 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 { ... }
中也不起作用。
[UPDATE/Summary]
接受的答案有效(在我从命令行中删除“-ti
”之后),正如@nischay goyal 所说,"please don't use -it as it opens the terminal and blocks 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
参数后起作用。
当然,就像所有 docker/Linux 阵营的人说的那样,使用 -d
。
总而言之,解决问题的方法有很多种。选择一个适合你的。
firefox 命令不需要任何标准输入,也不需要 tty。所以删除 -it
。接下来添加代表分离模式的 -d
,docker 内部 运行 守护进程的标准方式,或其他非交互式命令。
docker run -d --rm -e DISPLAY=$DISPLAY firefox
要完全执行 docker 中的命令并在后台使用 docker,您可以使用:
docker run $YourOption $ImageDocker exec $yourCommand
并且不要使用 -i -t 选项,它会打开终端
做类似的事情
docker run --rm -e DISPLAY=$DISPLAY firefox exec "ping google.com"
对于运行处于分离模式的docker容器,请不要使用-it
,因为它会打开终端并阻止它。
docker run --rm -e DISPLAY=$DISPLAY firefox
对于 运行在 PowerShell 中在后台运行命令,只要命令是可执行文件或具有关联可执行文件的文件,请使用 Start-Process(可从 v2 获得):
Start-Process -NoNewWindow ping google.com
在 PowerShell 后台使用 Start-Job
到 运行 命令。
在 PowerShell [Core] 6+ 中,您还可以将 &
放在命令的末尾,就像在 POSIX-like shell 中一样,例如Bash.
在这两种情况下,都会返回一个作业对象 (System.Management.Automation.PSRemotingJob
),您可以使用各种 *-Job
cmdlet 进行管理 - 请参阅 about_Jobs.
PowerShell 中的作业与 POSIX 类 shell 中的作业相似(例如 Bash) ,但存在一些 根本差异,特别是 inability 运行 interactive 命令背景 - 见 this comment on GitHub.
后台作业使用 子进程,它 运行 是后台隐藏的 PowerShell 实例,速度慢且资源密集。
因此考虑基于线程的Start-ThreadJob
cmdlet as a faster and more light-weight alternative - see .
语法也适用于 6 以下的 PowerShell 版本,Start-Job
:
# Preferable alternative: Start-ThreadJob
$job = Start-Job { docker run --rm -e DISPLAY=$using:DISPLAY firefox }
注:-ti
被删除,因为,如Nischay Goyal points out, it would open an interactive shell session, which means that the call wouldn't return until that session is manually closed. However, not that Start-Job
generally doesn't support running interactive programs in the background, as explained here.
注意需要通过 $using:
范围说明符在调用方范围内引用 $DISPLAY
变量 - 参见 about_Remote_Variables.
警告:在 6.x 之前的 PowerShell 版本中,以这种方式启动的后台作业使用与调用者无关的 固定 工作目录 - 请参阅 。
PowerShell [Core] 6+ 备选方案:将 &
放在命令末尾:
$job = docker run --rm -e DISPLAY=$DISPLAY firefox &
请注意,您 不需要 使用此语法的 $using:
范围说明符,即使在 PowerShell 6.x 中,该作业也会看到相同的工作目录来电者。
请注意,没有类似的简洁语法来创建 thread 作业(相当于 Start-ThreadJob
调用),但从 PowerShell 7.0 开始,但加一是this feature request on GitHub的主题。
如上所述,您可以使用其他各种 *-Job
cmdlet 管理 作业 一旦创建(它们还管理使用 Start-ThreadJob
创建的线程作业);例如,以下命令同步等待作业完成,打印其输出,然后删除作业。
$job | Receive-Job -Wait -AutoRemoveJob
至于你试过的:
ping google.com &
中的后置 &
不起作用,因为您 运行 正在使用 Windows PowerShell (PowerShell 版本高达 v5.1),而此语法需要 PowerShell [Core] 版本 6 或更高版本。
Start-Process
旨在异步启动可执行文件,默认情况下在新的 window 中(在 Windows 上)。
它主要用于在新控制台 window.
中启动 GUI 应用程序(异步)或 运行ning shell 命令
虽然它也可以不可见地启动进程,但您几乎无法控制该进程,并且只能通过文本文件间接捕获其输出。
您的调用失败的原因是您试图将直通参数直接传递给Start-Process
,而不是将它们传递给-ArgumentList
参数(作为单个字符串,在最简单的情况下)。
简单的问题,我想在后台执行运行 docker命令。
(实际上 运行 在 Powershell 下使用命令行参数执行任何命令是我真正的问题,但是 docker
是一个简单的具体问题)
我有一个命令
docker run -ti --rm -e DISPLAY=$DISPLAY firefox
运行在 Powershell 下没问题,但会阻塞。
我想运行使用 *nix:
下执行“&”的等效方法docker run -ti --rm -e DISPLAY=$DISPLAY firefox &
我试过了
- Powershell equivalent of bash ampersand (&) for forking/running background processes
但都不适合我:
> 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 { ... }
中也不起作用。
[UPDATE/Summary]
接受的答案有效(在我从命令行中删除“-ti
”之后),正如@nischay goyal 所说,"please don't use -it as it opens the terminal and blocks 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
参数后起作用。当然,就像所有 docker/Linux 阵营的人说的那样,使用
-d
。
总而言之,解决问题的方法有很多种。选择一个适合你的。
firefox 命令不需要任何标准输入,也不需要 tty。所以删除 -it
。接下来添加代表分离模式的 -d
,docker 内部 运行 守护进程的标准方式,或其他非交互式命令。
docker run -d --rm -e DISPLAY=$DISPLAY firefox
要完全执行 docker 中的命令并在后台使用 docker,您可以使用:
docker run $YourOption $ImageDocker exec $yourCommand
并且不要使用 -i -t 选项,它会打开终端
做类似的事情
docker run --rm -e DISPLAY=$DISPLAY firefox exec "ping google.com"
对于运行处于分离模式的docker容器,请不要使用-it
,因为它会打开终端并阻止它。
docker run --rm -e DISPLAY=$DISPLAY firefox
对于 运行在 PowerShell 中在后台运行命令,只要命令是可执行文件或具有关联可执行文件的文件,请使用 Start-Process(可从 v2 获得):
Start-Process -NoNewWindow ping google.com
在 PowerShell 后台使用 Start-Job
到 运行 命令。
在 PowerShell [Core] 6+ 中,您还可以将 &
放在命令的末尾,就像在 POSIX-like shell 中一样,例如Bash.
在这两种情况下,都会返回一个作业对象 (System.Management.Automation.PSRemotingJob
),您可以使用各种 *-Job
cmdlet 进行管理 - 请参阅 about_Jobs.
PowerShell 中的作业与 POSIX 类 shell 中的作业相似(例如 Bash) ,但存在一些 根本差异,特别是 inability 运行 interactive 命令背景 - 见 this comment on GitHub.
后台作业使用 子进程,它 运行 是后台隐藏的 PowerShell 实例,速度慢且资源密集。
因此考虑基于线程的Start-ThreadJob
cmdlet as a faster and more light-weight alternative - see
语法也适用于 6 以下的 PowerShell 版本,Start-Job
:
# Preferable alternative: Start-ThreadJob
$job = Start-Job { docker run --rm -e DISPLAY=$using:DISPLAY firefox }
注:-ti
被删除,因为,如Nischay Goyal points out, it would open an interactive shell session, which means that the call wouldn't return until that session is manually closed. However, not that Start-Job
generally doesn't support running interactive programs in the background, as explained here.
注意需要通过 $using:
范围说明符在调用方范围内引用 $DISPLAY
变量 - 参见 about_Remote_Variables.
警告:在 6.x 之前的 PowerShell 版本中,以这种方式启动的后台作业使用与调用者无关的 固定 工作目录 - 请参阅
PowerShell [Core] 6+ 备选方案:将 &
放在命令末尾:
$job = docker run --rm -e DISPLAY=$DISPLAY firefox &
请注意,您 不需要 使用此语法的 $using:
范围说明符,即使在 PowerShell 6.x 中,该作业也会看到相同的工作目录来电者。
请注意,没有类似的简洁语法来创建 thread 作业(相当于 Start-ThreadJob
调用),但从 PowerShell 7.0 开始,但加一是this feature request on GitHub的主题。
如上所述,您可以使用其他各种 *-Job
cmdlet 管理 作业 一旦创建(它们还管理使用 Start-ThreadJob
创建的线程作业);例如,以下命令同步等待作业完成,打印其输出,然后删除作业。
$job | Receive-Job -Wait -AutoRemoveJob
至于你试过的:
ping google.com &
中的后置 &
不起作用,因为您 运行 正在使用 Windows PowerShell (PowerShell 版本高达 v5.1),而此语法需要 PowerShell [Core] 版本 6 或更高版本。
Start-Process
旨在异步启动可执行文件,默认情况下在新的 window 中(在 Windows 上)。
它主要用于在新控制台 window.
虽然它也可以不可见地启动进程,但您几乎无法控制该进程,并且只能通过文本文件间接捕获其输出。
您的调用失败的原因是您试图将直通参数直接传递给Start-Process
,而不是将它们传递给-ArgumentList
参数(作为单个字符串,在最简单的情况下)。