Подтвердить что ты не робот

Python: Как получить stdout после запуска os.system?

Я хочу получить stdout в переменной после запуска вызова os.system.

Давайте возьмем эту строку в качестве примера:

batcmd="dir"
result = os.system(batcmd)

result будет содержать код ошибки (stderr 0 под Windows или 1 в некоторых Linux для приведенного выше примера).

Как я могу получить stdout для вышеуказанной команды, не используя перенаправление в выполненной команде?

4b9b3361

Ответ 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)