【问题标题】:Open terminal and run command inside docker using python使用 python 打开终端并在 docker 中运行命令
【发布时间】:2020-06-28 22:01:26
【问题描述】:

我想从 docker 容器中运行 ssh 端口转发命令(应在新终端窗口或等效窗口中打开)。我有一个 python script 可以在我的本地 ubuntu 上完美地做到这一点。

import os
command = "ssh -4 -N -L 322:localhost:322 toing@localhost -p 654"
os.system("gnome-terminal -e 'bash -c \"" + command + ";bash\"'")

但是,当我在 docker 容器中尝试此命令时,出现以下错误:

选项“-e”已弃用,可能会在更高版本的 gnome-terminal 中删除。

使用“--”终止选项,并在其后放置要执行的命令行。

无法连接到无障碍总线:无法连接到套接字 /tmp/dbus-XETYD1whMB:连接被拒绝

未能加载模块“canberra-gtk-module”

未能加载模块“canberra-gtk-module”

我正在使用以下命令运行 docker 映像(显示实际上是针对脚本中的另一个进程):

docker run -it  -e DISPLAY=$DISPLAY  -v /tmp/.X11-unix:/tmp/.X11-unix -p 8090:8090 xxxxxxx

我也尝试在容器内的python终端运行相同的命令,但得到以下响应:

>>> os.system("gnome-terminal -e 'bash -c \"" + command + ";bash\"'")
# Option “-e” is deprecated and might be removed in a later version of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to execute after it.
# Couldn't connect to accessibility bus: Failed to connect to socket /tmp/dbus-XETYD1whMB: Connection refused
# Failed to load module "canberra-gtk-module"
# Failed to load module "canberra-gtk-module"
# Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: Failed to execute child process “dbus-launch” (No such file or directory)
256

我需要这个打开的终端在后台运行,我该如何实现呢?

【问题讨论】:

  • 我有点疑惑。为什么要在终端中运行端口转发?还不能在后台运行它吗?无论如何,如果你把一个像“echo foo”这样的短命令放在一起在 gnome-terminal 下运行,如果它有效,然后从那里慢慢建立你最终想要的命令。
  • 为什么要从 Docker 容器中运行它?如果command 包含引号或分号等标点符号会怎样?
  • 在容器内配置了 SSH 连接所需的 vpn。我使用子进程解决了这个问题。很快就会更新答案

标签: python bash docker


【解决方案1】:

因此,我没有打开终端,而是按照@dstromberg 的建议使用子进程在后台运行它。 我最初想使用终端方法,因为 SSH 连接需要一个是/否 anwser 来添加指纹,然后还要输入密码。毕竟 SSH 连接没有使用默认端口。

然而,这一切都可以使用子进程来实现。 首先你需要使用安装sshpass

sudo apt-get install sshpass

之后,

import subprocess
command = ['sshpass', '-p', 'imnottellingyou', 'ssh', '-oStrictHostKeyChecking=accept-new',  '-4', '-N', '-L',  '55:localhost:55', 'toing@localhost', '-p', '654',]
proc = subprocess.Popen(command, close_fds=True)
# now do whatever you want (the code, please)

然后做你的事情,然后当你想杀死端口转发时:

proc.kill()

由于kill()不起作用sometimes,你也可以试试:

import signal
import os

p_id = os.getpgid(proc.pid)
os.killpg(p_id, signal.SIGTERM)

对于 SSH 中的 -4 选项,它强制使用 IPv4。 瞧!无需复杂的后台终端内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多