Python 读取管道时子进程不工作
我自己创建并使用QGIS工具插件 总之,插件需要逻辑来确保用户安装了Java 因此,我尝试运行java-version并在输出出来时传递输出 但是,没有打印Java版本 这是我的来源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() #
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
库。这要简单得多。@GiacomoAlzettashell=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)