Python 读取管道时子进程不工作

Python 读取管道时子进程不工作,python,subprocess,Python,Subprocess,我自己创建并使用QGIS工具插件 总之,插件需要逻辑来确保用户安装了Java 因此,我尝试运行java-version并在输出出来时传递输出 但是,没有打印Java版本 这是我的来源 try: check_process = subprocess.Popen(["java", "-version", "2>&1"], stderr=subprocess.PIPE) check_process = check_process.communicate() #

我自己创建并使用QGIS工具插件

总之,插件需要逻辑来确保用户安装了Java

因此,我尝试运行java-version并在输出出来时传递输出

但是,没有打印Java版本

这是我的来源

try:
    check_process = subprocess.Popen(["java", "-version", "2>&1"], stderr=subprocess.PIPE)
    check_process = check_process.communicate()

    # this is print func
    QgsMessageLog.logMessage(str(check_process), tag="Validating", level=QgsMessageLog.INFO)

except Exception as e:
    QgsMessageLog.logMessage(str(e), tag="Validating", level=QgsMessageLog.INFO)
    return
结果是

2018-09-21T09:36:21 0   (None, '')
如果你有任何想法,我将感谢你的建议。多谢各位

问题:子流程不工作

您正在使用
2>&1
,这是一个Shell命令,只有在使用
Shell=True
后才能工作。 您可以将
stderr
重定向到
stdout
,因为
java-version
将写入
stderr

例如,这样做:(注意您的差异,无列表和标准输出=!

由于这将为我获得预期的输出,因此您可以使用以下方法获得
(无“”)

check_process = subprocess.Popen(["java", "-version", "2>&1"], stderr=subprocess.PIPE)
第一个元组是
stdout
的输出,它不在
Popen
中使用
第二个元组是
stderr
的输出,它是空字符串

出于测试目的,请在内部
QGIS

result = subprocess.check_output(["echo", "Hello World!"])
print(result)

注意:
“2>&1”
在您的情况下不起任何作用<如果未指定
shell=True
,则code>Popen不会解释shell语法。如果要将
stderr
重定向到
stdout
请使用
stdout=subprocess.PIPE,stderr=subprocess.stdout
,如果要将
stdout
重定向到
stderr
请使用
stdout=subprocess.stderr,stderr=subprocess.PIPE
。注意:如果您想使用
shell=True
:1)不要,这是一个安全问题2)参数应该是一个字符串,而不是一个列表
Popen(“java-version 2>&1”,shell=True)
(不推荐)。请尝试使用
pexpect
库。这要简单得多。@GiacomoAlzetta
shell=True
是一个安全问题,其方式与sql注入相同。只要表达式中没有运动部件、变量或其他修改方式,这就不是问题。但是,仍然存在开销,因为系统将打开一个额外的子进程;它将打开一个shell进程,然后该进程将执行您想要的进程,即在这种情况下,
java
。@JohanL您错了。从来没有听说过SHELLSHOCK?它使shell的所有使用都易受攻击,即使命令是固定字符串。当然,新系统应该是固定的(但请记住,大量的系统已经过时或没有正确地进行修补),它仍然需要一些特殊的条件才能做到,但并不是说
shell=true
像SQLi一样是一个安全问题。更糟。因此,你应该不惜一切代价避免它,直到你不得不这样做,如果你使用
shell=True
,你也应该使用
env=
,并且只在env中保留你知道需要的东西。@GiacomoAlzetta虽然我完全同意不使用
shell=True
,而且影响更大,安全问题本身,仍然与SQL注入的类型相同。然而,我同意这种影响可能更糟,特别是由于SHELLSHOCK(我实际上没有听说过),而且通常最好不要使用
shell=True
。然而,只是简单地说使用它是危险的,应该不惜一切代价避免使用,而不说为什么,对情况没有帮助。原谅我迟到了。现在去韩国度假已经太晚了。我根据您提供的示例运行了它,但它不起作用<代码>以subprocess.Popen([“java”,“-version”],stdout=subprocess.PIPE)作为进程:,结果是
2018-09-28009:24:00 0错误:\uuuuu exit\uuuuu
直接从cmd运行java-version时效果很好,但我不知道该解决方案,因为它在QGIS环境中的应用似乎有所不同,我不知道。错误表明您正在使用Python2.x。
supprocess
模块不同。我已经重写了关于错误结论和Python 2.x版的回答。
result = subprocess.check_output(["echo", "Hello World!"])
print(result)