【问题标题】:Executing processes with python by subprocess library通过子进程库使用python执行进程
【发布时间】:2014-02-06 10:23:38
【问题描述】:

我刚刚在 python 中创建了一个软件,它应该从 shell 调度几个命令。 (ps:我在linux上工作) 顺便说一句,我创建了以下函数来启动进程:

def exec_command(cmd):
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
pid = process.pid
print '----------launched process with PID: ', pid 
return pid

在此之后,我使用 pid 检查进程是否进入僵尸状态,在这种情况下将其杀死。 有时一切正常,但在某些情况下,启动的进程没有做任何事情。 我说的过程是:sh /home/ubuntu/programs/data-integration/kitchen.sh -file=/home/ubuntu/TrasformazioneAVM/JobAVM.kjb -level=Basic -param:processName=avm
如果我通过 shell 启动它,一切正常,但如果我用我的函数执行它,我可以在系统监视器上看到进程(或通过 shell 使用“top”命令)但没有任何结果(我检查内存使用情况和 cpu 使用情况通常非常高,但在这种情况下不是)。 任何机构有什么想法吗?

【问题讨论】:

  • 你能写出print cmd的输出吗
  • “打印 CMD”是什么意思?
  • 我的意思是你把 cmd 作为一个列表还是一个字符串
  • 这是字符串:sh /home/ubuntu/programs/data-integration/kitchen.sh -file=/home/ubuntu/TrasformazioneAVM/JobAVM.kjb -level=Basic -param:processName= avm

标签: python linux subprocess popen


【解决方案1】:
stdout=subprocess.PIPE

这是罪魁祸首。您正在将您的子进程输出重定向到一个管道,但您不是从该管道读取数据。

您可以从中读取(如果您需要该进程创建的输出),或者完全删除重定向。

编辑:

如果您希望将输出重定向到 /dev/null,考虑到您通过 shell (shell=True) 启动命令,最简单的解决方案是将> /dev/null 附加到cmd 字符串。如果它也打印到​​标准错误,那么你需要>/dev/null 2>&1

一个更好的解决方案,不需要通过 shell 启动你的命令,如下:

如果您使用的是 Python 3.3 或更高版本,只需传递 subprocess.DEVNULL 常量:

subprocess.Popen(cmd, stdout=subprocess.DEVNULL, shell=True, preexec_fn=os.setsid)

如果没有,或者你想保持向后兼容性,只需打开 /dev/null 并传递它:

subprocess.Popen(cmd, stdout=open(os.devnull, "w"), shell=True, preexec_fn=os.setsid)

【讨论】:

  • 我认为我必须创建一个管道,因为当我启动进程时会生成许多 pid,当我杀死其中一个时,我希望所有连接的进程都死掉
  • @user2637212 你不必使用管道来做到这一点。孩子收到 SIGPIPE 并在尝试写入另一端关闭的管道时死亡,这更像是副作用。例如,您可以使用进程组。还记得在控制台中按 ^C 会中断所有子进程吗?它是通过向整个进程组发送 SIGINT 来实现的。你也可以这样做。
  • 那么你建议用什么来代替 stdout=subprocess.PIPE ?
  • @user2637212 你需要程序打印的输出吗?如果您只需要自己查看,请删除 stdout 参数(或将其设置为 None)。输出将打印到您的 shell。如果您根本不需要输出,您可以通过打开它来将其重定向到 /dev/null 以写入并传递结果文件对象。如果您的 python 脚本需要以某种方式解释输出(解析它等),那将会更加困难,而且这是一个完全不同的故事。
  • 好的,我将“stdout”设置为无,现在一切正常。正如你所说,它会在我的 shell 上打印输出。我想将它重定向到 /dev/null。我该怎么做?
【解决方案2】:

试试下面

def exec_command(cmd):
    cmd = cmd.split()
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, preexec_fn=os.setsid)
    pid = process.pid
    print '----------launched process with PID: ', pid 
    return pid

【讨论】:

  • 回应是什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 2020-05-16
  • 1970-01-01
  • 2012-05-19
  • 2015-10-22
  • 2012-10-15
相关资源
最近更新 更多