Python: Как получить stdout после запуска os.system?
Я хочу получить stdout
в переменной после запуска вызова os.system
.
Давайте возьмем эту строку в качестве примера:
batcmd="dir"
result = os.system(batcmd)
result
будет содержать код ошибки (stderr
0
под Windows или 1
в некоторых Linux для приведенного выше примера).
Как я могу получить stdout
для вышеуказанной команды, не используя перенаправление в выполненной команде?
Ответы
Ответ 1
Если вам нужен только вывод stdout
, взгляните на subprocess.check_output()
:
import subprocess
batcmd="dir"
result = subprocess.check_output(batcmd, shell=True)
Поскольку вы использовали os.system()
, вам нужно установить shell=True
, чтобы получить то же поведение. Вы действительно хотите учесть проблемы безопасности, связанные с передачей ненадежных аргументов в вашу оболочку.
Если вам нужно также захватить stderr
, просто добавьте stderr=subprocess.STDOUT
к вызову:
result = subprocess.check_output([batcmd], stderr=subprocess.STDOUT)
чтобы перенаправить вывод ошибок в поток вывода по умолчанию.
Если вы знаете, что вывод текста, вы можете
Ответ 2
Эти ответы не помогли мне. Мне пришлось использовать следующее:
import subprocess
p = subprocess.Popen(["pwd"], stdout=subprocess.PIPE)
out = p.stdout.read()
print out
Или как функция (с использованием оболочки = True для меня требуется Python 2.6.7, а check_output не добавляется до 2.7, что делает ее непригодной для использования):
def system_call(command):
p = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True)
return p.stdout.read()
Ответ 3
Я хотел бы расширить решение Windows. Использование IDLE с Python 2.7.5, Когда я запускаю этот код из файла Expts.py:
import subprocess
r = subprocess.check_output('cmd.exe dir',shell=False)
print r
... в оболочке Python я ТОЛЬКО получаю вывод, соответствующий "cmd.exe"; часть "dir" игнорируется. ОДНАКО, когда я добавляю такой переключатель, как /K или/C...
import subprocess
r = subprocess.check_output('cmd.exe /K dir',shell=False)
print r
... затем в оболочке Python я получаю все, что ожидаю, включая список каталогов. Woohoo!
Теперь, если я пробую любую из этих же вещей в командном окне DOS Python, без коммутатора или с помощью переключателя /K, похоже, что окно зависает, потому что он запускает подпроцесс cmd.exe и ожидает дальнейшего input - введите "exit", затем нажмите [enter], чтобы отпустить. Но с переключателем /K он отлично работает и возвращает вас в приглашение python. Тогда отдайте предпочтение.
Сделал еще один шаг... Я думал, что это круто... Когда я вместо этого делаю это в Expts.py:
import subprocess
r = subprocess.call("cmd.exe dir",shell=False)
print r
... открывается новое окно DOS и остается там, где отображаются только результаты "cmd.exe", а не "dir" . Когда я добавляю переключатель /C, окно DOS открывается и закрывается очень быстро, прежде чем я смогу что-либо увидеть (как ожидалось, потому что /C завершается, когда это делается). Когда я вместо этого добавляю переключатель /K, окно DOS всплывает и остается, И я получаю весь вывод, который я ожидаю, включая список каталогов.
Если я попробую то же самое (subprocess.call вместо subprocess.check_output) из окна команд DOS Python; весь вывод находится в одном окне, нет всплывающих окон. Без коммутатора снова игнорируется часть "dir" , а приглашение изменяется из приглашения python в подсказку DOS (поскольку подпроцесс cmd.exe запущен в python, снова введите "exit", и вы вернетесь к приглашению python). Добавление переключателя /K распечатывает список каталогов и изменяет подсказку с python на DOS, поскольку /K не завершает подпроцесс. Изменение переключателя на /C дает нам весь ожидаемый результат И возвращается в приглашение python, так как подпроцесс завершается в соответствии с /C.
Извините за долгожданный ответ, но я расстроен на этой доске множеством кратких "ответов", которые в лучшем случае не работают (кажется, потому что они не протестированы - как ответ Eduard F выше моего, который отсутствует переключатель) или, что еще хуже, настолько кратки, что они вообще ничего не помогают (например, "попробуйте подпроцесс вместо os.system"... да, хорошо, теперь что?). Напротив, я предоставил решения, которые я тестировал, и показал, как между ними существуют тонкие различия. Взял много времени, но...
Надеюсь, это поможет.
Ответ 4
commands
также работает.
import commands
batcmd = "dir"
result = commands.getoutput(batcmd)
print result
Он работает на linux, python 2.7.
Ответ 5
Мне пришлось использовать os.system, так как подпроцесс выдавал ошибку памяти для больших задач. Ссылка на эту проблему здесь. Итак, чтобы получить вывод команды os.system, я использовал этот обходной путь:
import os
batcmd = 'dir'
result_code = os.system(batcmd + ' > output.txt')
if os.path.exists('output.txt'):
fp = open('output.txt', "r")
output = fp.read()
fp.close()
os.remove('output.txt')
print(output)
Ответ 6
import subprocess
string="echo Hello world"
result=subprocess.getoutput(string)
print("result::: ",result)