在Python子进程中在docker中运行交互式命令

时间:2014-12-09 12:04:58

标签: python bash shell docker

当我在交互模式下使用docker run时,我能够运行我想测试一些python的命令。

root@pydock:~# docker run -i -t dockerfile/python /bin/bash
[ root@197306c1b256:/data ]$ python -c "print 'hi there'"
hi there
[ root@197306c1b256:/data ]$ exit
exit
root@pydock:~#

我想使用子进程模块从python自动执行此操作,所以我写了这个:

run_this = "print('hi')"
random_name = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(20))
command = 'docker run -i -t --name="%s" dockerfile/python /bin/bash' % random_name
subprocess.call([command],shell=True,stderr=subprocess.STDOUT)
command = 'cat <<\'PYSTUFF\' | timeout 0.5 python | head -n 500000 \n%s\nPYSTUFF' % run_this
output = subprocess.check_output([command],shell=True,stderr=subprocess.STDOUT)
command = 'exit'
subprocess.call([command],shell=True,stderr=subprocess.STDOUT)
command = 'docker ps -a | grep "%s" | awk "{print $1}" | xargs --no-run-if-empty docker rm -f' % random_name
subprocess.call([command],shell=True,stderr=subprocess.STDOUT)

这应该创建容器,在容器上运行python命令并退出并删除容器。除了命令在主机而不是docker容器上运行外,它完成所有这些操作。我想码头工人正在切换贝壳或类似的东西。如何从新she​​ll运行python子进程?

2 个答案:

答案 0 :(得分:2)

看起来您期望第二个命令cat <<...将输入发送到第一个命令。但是这两个子进程命令之间没有任何关系,所以这不起作用。

Python的subprocess library和作为其基础的popen命令提供了一种方法来获取进程的标准输入管道。这样,您可以直接从Python发送所需的命令,而不必尝试让另一个子进程与之通信。

所以,比如:

from subprocess import Popen, PIPE

p = Popen("docker run -i -t --name="%s" dockerfile/python /bin/bash", stdin=PIPE)
p.communicate("timeout 0.5 python | head -n 500000 \n" % run_this) 

(我不是Python专家;为字符串形成中的错误道歉。改编自this answer

答案 1 :(得分:1)

您实际上需要在正在打开的新shell上生成一个新子项。所以在docker creation运行docker enter之后或尝试使用pexpect而不是子进程执行相同的操作.pexpect spawns一个新的孩子,这样你就可以发送命令。