简体   繁体   English

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

[英]Running interactive commands in docker in Python subprocess

When I use docker run in interactive mode I am able to run the commands I want to test some python stuff. 当我在交互模式下使用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:~#

I want to automate this from python using the subprocess module so I wrote this: 我想使用子进程模块从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)

This is supposed to create the container, run the python command on the container and exit and remove the container. 这应该是创建容器,在容器上运行python命令并退出并删除容器。 It does all this except the command is run on the host machine and not the docker container. 除了命令在主机而不是docker容器上运行外,它完成所有这些操作。 I guess docker is switching shells or something like that. 我想码头工人正在切换贝壳或类似的东西。 How do I run python subprocess from a new shell? 如何从新she​​ll运行python子进程?

It looks like you are expecting the second command cat <<... to send input to the first command. 看起来你期望第二个命令cat <<...将输入发送到第一个命令。 But the two subprocess commands have nothing to do with each other, so this doesn't work. 但是这两个子进程命令彼此无关,所以这不起作用。

Python's subprocess library , and the popen command that underlies it, offer a way to get a pipe to stdin of the process. Python的subprocess popen 以及作为其基础的popen命令提供了一种方法来获取进程的stdin管道。 This way, you can send in the commands you want directly from Python and don't have to attempt to get another subprocess to talk to it. 这样,您可以直接从Python发送您想要的命令,而不必尝试让另一个子进程与之通信。

So, something like: 所以,像:

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) 

(I'm not a Python expert; apologies for errors in string-forming. Adapted from this answer ) (我不是Python专家;对于字符串形成中的错误道歉。改编自这个答案

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM