当linux通过subprocess.Popen()被调用时,我有一个意想不到的行为。
Python脚本的结构如下:
import os, subprocess
def _degrade_child_rights(user_uid, user_gid):
def result():
os.setgid(user_gid)
os.setegid(user_gid)
os.setuid(user_uid)
os.seteuid(user_uid)
return result
child = subprocess.Popen("cat /home/myuser/myfolder/screenlog.0",
preexec_fn=_degrade_child_rights(0, 0), shell=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
当我使用ps aux \ grep cat检查已执行的shell命令时,它将显示python成功地运行shell命令。
> ps aux | grep cat
root 21236 0.0 0.0 6564 780 pts/1 S 20:49 0:00 /bin/sh -c cat /home/myuser/myfolder/screenlog.0
root 21237 0.0 0.0 11056 732 pts/1 S 20:49 0:00 cat /home/myuser/myfolder/screenlog.0
root 21476 0.0 0.0 15800 936 pts/1 S+ 20:52 0:00 grep --color=auto cat
然而,cat命令从未完成。
我还将cat $file命令外包给bash脚本。然后bash执行我的猫调用,但也阻塞。
当我手动执行cat $file时,它按预期运行,所以文件末尾不存在EOF也是不可能的。
我认为,Popen -c添加的'/bin/sh‘在某种程度上与cat $file的正确执行有关。
我能阻止这一切吗?
发布于 2017-08-18 11:21:53
您可能想尝试一下Popen对象的通信方法:
Popen.communicate(input=None)
与进程交互:将数据发送到stdin。从stdout和stderr读取数据,直到文件结束.等待进程终止。可选的输入参数应该是要发送到子进程的字符串,如果不应该向子进程发送数据,则为None。communicate()
返回一个元组(stdoutdata,stderrdata)。 注意,如果要将数据发送到进程的stdin,则需要使用stdin=PIPE创建Popen对象。类似地,要在结果元组中获得除“无”之外的任何内容,还需要给出stdout=PIPE和/或stderr=PIPE。 注意,数据读取是在内存中缓冲的,因此,如果数据大小很大或无限,请不要使用此方法。
在 python doc中有更多的信息
https://stackoverflow.com/questions/45763567
复制相似问题