Python subprocess.Popen()在Docker容器中无法工作 - 本地正常运行

9
我创建了一个Django REST框架项目,想要在服务器上部署。由于我没有管理员权限,所以我找到的确保所有项目依赖项(如Anaconda分发)可用于服务器的唯一方法是为我的项目创建一个docker镜像,然后在服务器上创建相应的容器,从那里运行它。
在我的项目中,我有一个python脚本(mymain.py),使用subprocess.Popen()调用它。这在本地工作正常,subprocess.Popen()也能够完成它应该做的一切。
然而,当我尝试从docker容器中执行时,似乎完全跳过了subprocess.Popen()这一行[mymain.py没有被调用]。
对于docker,我创建了一个docker-compose.yml文件,在命令提示符中输入:
docker-compose up

我没有看到任何错误,一切似乎运行良好,但是 subprocess.Popen() 似乎无法工作。

mymain.py 的第一行是:

print('Testing if subprocess called mymain.py!!!')  

在另一个文件中,我调用了 subprocess.Popen() 方法。我尝试将错误信息打印出来,但是不幸的是,无论是 stdout 还是 stderr 都没有返回任何内容。
p = subprocess.Popen(['python', mymain_path, args], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
out, err = p.communicate()
print('SUBPROCESS ERROR: ' + str(err))
print('SUBPROCESS stdout: ' + str(out.decode()))    

这是我得到的结果:
SUBPROCESS ERROR: None
SUBPROCESS stdout:

正如您所看到的,我的main.py文件的第一行从未被打印出来...

然而,当我在命令提示符中键入以下内容时,这种情况在本地环境下不会发生:

python manage.py runserver 9000

所有东西都可以正常工作(会打印出“Testing if subprocess called mymain.py!!!”这一行)。

我甚至尝试打开docker容器的shell,然后在里面输入相同的“python manage.py runserver 9000”命令,但不幸的是它没有起作用。

现在问题是,如何让子进程在远程(docker容器中)工作?

非常感谢任何关于此的帮助!

我正在使用:

Docker version 18.09.2, build 6247962
docker-compose version 1.23.2, build 1110ad01
Python 3.7.0
2个回答

5
看起来解决此问题的方法是: 1. 使用 'shell=False' 2. 不要为 'subprocess.Popen()' 提供返回值。
subprocess.Popen(['python', mymain_path, args], shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

这对我非常有帮助! 看起来 shell=True 似乎会隐藏 stdout,特别是在出错时! 我建议将此标记为被接受的答案。 附言:在 Python 调用中添加 -u 解决了我的问题(我需要 shell=True),因为如果发生异常,shell 似乎不会刷新输出! - Dani K

1

我遇到了完全相同的问题,之前的解决方法都没有起作用。

最后我尝试了

print("Hello world!", flush=True)

这在我的环境中似乎可以工作(docker,python3.7)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接