通过subprocess.Popen()调用cat阻塞

时间:2017-08-18 19:09:41

标签: python linux bash python-2.7 shell

我通过subprocess.Popen()调用了linux cat的意外行为。

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 |检查执行的shell命令时grep cat它告诉我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-call,但也阻止。

当我手动执行cat $文件时,它会按预期运行,因此文件末尾不存在EOF也是不可能的。

我认为,' / bin / sh -c' Popen以某种方式添加了cat $ file的正确执行。

我可以以某种方式阻止这种情况吗?

1 个答案:

答案 0 :(得分:1)

您可能想尝试Popen对象的通信方法:

  

Popen.communicate(input=None)   与流程交互:将数据发送到   标准输入。从stdout和stderr读取数据,直到达到文件结尾。   等待进程终止。可选的输入参数应为a   要发送到子进程的字符串,如果没有数据,则为None   寄给孩子。

     

communicate()返回一个元组(stdoutdata,stderrdata)。

     

请注意,如果要将数据发送到进程的stdin,则需要   使用stdin = PIPE创建Popen对象。同样,得到任何东西   除了结果元组中的None之外,你需要给stdout = PIPE   和/或stderr = PIPE。

     

注意读取的数据缓冲在内存中,因此请勿使用此方法   数据大小很大或无限制。

subprocess python doc

中有更多信息