Я создаю и использую сам инструмент Plugin 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
.
Сделайте это, например: (Обратите внимание на различия, нет списка и stdout =, на ваш!)
check_process = subprocess.Popen("java -version 2>&1", shell=True, stdout=subprocess.PIPE)
Поскольку это даст ожидаемый результат для меня, вы получите (None, '')
используя:
check_process = subprocess.Popen(["java", "-version", "2>&1"], stderr=subprocess.PIPE)
Первый кортеж - выход stdout
который не используется в Popen
.
Второй кортеж - это вывод stderr
который является пустой строкой.
Для тестирования попробуйте в QGIS
:
result = subprocess.check_output(["echo", "Hello World!"])
print(result)
with subprocess.Popen(["java", "-version"], stdout=subprocess.PIPE) as proc:
и результат 2018-09-28T09:24:00 0 Error : __exit__
Хорошо работает, когда я запускаю java -version непосредственно из cmd, но я не знаю решение, потому что оно, кажется, применяется по-другому к среде QGIS, которую я не знаю.
supprocess
отличается. Я переписал свой ответ на неправильные выводы и версию Python 2.x.
"2>&1"
ничего не делает в вашем случае.Popen
не интерпретирует синтаксис оболочки, если вы не укажетеshell=True
. Если вы хотите перенаправить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
. Это намного проще.