使用上下文管理器的Popen

3

我一直在尝试编写一个函数,通过参数传递命令并使用POPEN和上下文管理器来执行它。不幸的是,我无法让它正常工作。请问有人可以帮忙吗?

import os
import sys
import subprocess
import inspect    

def run_process(cmd_args):
    with subprocess.Popen(cmd_args, stdout=subprocess.PIPE) as proc:
        log.write(proc.stdout.read())

run_process("print('Hello')")

期望的输出是"Hello",请问哪里出了问题?

也许您正在寻找multiprocessing模块?subprocess用于与外部程序进行交互。 - tripleee
2
供参考,使用上下文管理器的 subprocess.Popen 支持已在 Python 3.2 中记录 - 0 _
4个回答

2

如果您正在通过子进程运行bash命令,那么您所做的是正确的。

在上下文管理器“with ...”中,您所做的是从终端读取输出并将其存储为字节(byte(s))形式在“output”变量中,并尝试在解码后以ASCII格式打印出字节。

尝试从上下文管理器中返回值,然后在调用函数中进行解码:

import os
import sys
import subprocess
import inspect    

def run_process(cmd_args):          # Below added shell=True' in parameters.
    with subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=True) as proc: 
        return proc.stdout.read()  # returns the output 
                               # Optionally you can use the 'encoding='utf-8' argument 
                               # instead and just print(proc.stdout.read()).   
print(run_process().decode('utf-8')) 

我在将一个进程传输到另一个程序时遇到了类似的问题,然后我在另一个程序中进行了解码,出乎意料地它起作用了。希望这对你也有帮助。


1
def run_process(cmd_args):
    with subprocess.Popen(cmd_args, stdout=subprocess.PIPE) as p:    
        output = p.stdout.read() 
        return output

它对于相同的问题起作用。


0

Popen()函数接收的命令会像在终端中输入一样执行(例如:Windows上的CMD或Linux上的bash)。因此,它不执行Python代码,而是执行Bash代码(例如,在Linux上)。Python二进制文件有一个命令-c,可以立即执行Python命令。 因此,您有两个选项:

  • 要么使用echo Hello(在Windows或Linux上有效,echo同时适用于批处理和bash)
  • 要么使用python -c "print('Hello') 而不是仅使用print命令。

我使用了 p = subprocess.Popen(["echo", "hello world"], stdout=subprocess.PIPE) print p.communicate() 这段代码,它可以正常工作。但是我该如何在这个过程中使用上下文管理器呢?如果我使用 with subprocess.Popen(["echo", "hello world"], stdout=subprocess.PIPE) as p: p.communicate() 这样的上下文管理器,它会失败。有什么帮助吗? - Matthew
1
对我来说它正常工作。我唯一能看到的是,在使用上下文时,您忘记了打印。以下两个Python文件在Python 3.6.4中为我输出相同的内容:import subprocess with subprocess.Popen(["echo", "hello world"], stdout=subprocess.PIPE) as p: print(p.communicate())import subprocess p = subprocess.Popen(["echo", "hello world"], stdout=subprocess.PIPE) print(p.communicate()) - Bogdan Condurache

0

在不对您现有的脚本进行太多更改的情况下,我已经编辑了您的脚本,并使用以下注释指示我所做的工作。希望这能帮到您。

import os
import sys
import subprocess
import inspect    

def run_process(cmd_args):          # Below added shell=True' in parameters.
    with subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=True) as proc: 
        output = proc.stdout.read()   # Reads the output from the process in bytes.
        print(output.decode('utf-8'))  # Converts bytes to UTF-8 format for readability. 
                                   # Optionally you can use the 'encoding='utf-8' argument 
                                   # instead and just print(proc.stdout.read()).   
run_process("echo Hello")  # To display the message in the prompt use 'echo' in your string like this.

注意:在使用shell=True之前,请阅读安全注意事项部分。https://docs.python.org/3/library/subprocess.html#security-considerations

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