【问题标题】:Python subprocess hangsPython子进程挂起
【发布时间】:2017-02-28 05:13:23
【问题描述】:

我正在执行以下子进程...

p.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"])

...它挂了。

但是如果我执行kmwe236@kmwe236:~/CS485/prog3/target26$ ./hex2raw < exploit4.txt | ./rtarget 那么它执行得很好。使用输入或管道操作符有什么问题吗?

我也试过sp.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"], shell=True)

整个代码如下所示UPDATED WITH SUGGESTIONS

import subprocess as sp
import pdb

for i in range(4201265,4201323):
    pdb.set_trace()
    d = hex(i)[2:]
    output = " "
    for i in range(len(d),0,-2):
        output = output + d[i-2:i] + " "

    out_buffer = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + output + "00 00 00 00"

    text_file = open("exploit4.txt", "w")
    text_file.write("%s" % out_buffer)

 #   sp.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"], shell=True)
    with open("exploit4.txt") as inhandle:
        p = sp.Popen("./hex2raw",stdin=inhandle,stdout=sp.PIPE)
        p2 = sp.Popen("./rtarget",stdin=p.stdout,stdout=sp.PIPE)
        [output,error] = p2.communicate()

我得到一个错误是

  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 8] Exec format error

调试后发生在触发子进程调用p = sp.Popen("./hex2raw",stdin=inhandle,stdout=sp.PIPE)

【问题讨论】:

  • 写完后别忘了关闭文件。
  • 另外,作为一般规则,不要将问题中的代码更新为最佳答案,否则您的问题将变得毫无意义。

标签: python subprocess


【解决方案1】:

由于您使用重定向和管道,您必须启用shell=True

sp.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"],shell=True)

但是在两个可执行文件上使用Popen 并输入exploit4.txt 的内容作为输入会更简洁。以下示例,适用于您的情况:

import subprocess

    with open("exploit4.txt") as inhandle:
        p = subprocess.Popen("./hex2raw",stdin=inhandle,stdout=subprocess.PIPE)
        p2 = subprocess.Popen("./rtarget",stdin=p.stdout,stdout=subprocess.PIPE)
        [output,error] = p2.communicate()
        print(output)
        # checking return codes is also a good idea
        rc2 = p2.wait()
        rc = p.wait()

解释:

  1. 打开输入文件,获取其句柄inhandle
  2. 打开第一个子进程,将stdininhandlestdout 重定向到输出流。获取管道句柄 (p)
  3. 打开第二个子进程,将 stdin 与前一个进程 stdoutstdout 重定向到输出流
  4. 让第二个进程communicate。它将通过消耗其输出来“拉”第一个:两个进程都以管道方式工作
  5. 获取返回码并打印结果

注意:您会收到“格式错误”,因为一个或两个可执行文件实际上是 shell 或其他非本机可执行文件。在这种情况下,只需将shell=True 选项添加到相关的Popen 调用中即可。

【讨论】:

  • 我试过了,还是不行。 Popen 语法是什么?
  • 我正在使用 2 个 grep 命令编写一个示例,并且已根据您的情况对其进行了调整。
  • 语义看起来不错,但还是有问题——检查帖子(更新了新代码和错误)
  • 哦,那一定是 shell 脚本。尝试为shell脚本的可执行文件添加shell=True(如果您不知道,请尝试在文本编辑器中打开它们),这次效果会更好:)
  • 它运作良好 - 谢谢。我只想说 rc2 = p2.wait() 和 rc = p.wait() 有点令人困惑(因为您不再等待,只需获取状态码),我认为这对可读性有点不利。
猜你喜欢
  • 2012-09-07
  • 2015-07-07
  • 2013-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
相关资源
最近更新 更多