чтение os.popen (команды) в строку

Я не уверен, что мое название правильное. Что я делаю, так это пишу скрипт на Python, чтобы автоматизировать написание некоторого кода. Итак, я разбираю файл .h. но я хочу развернуть все макросы, прежде чем начать. поэтому я хочу вызвать оболочку, чтобы:

gcc -E myHeader.h

Что должно вывести предварительно обработанную версию myHeader.h на стандартный вывод. Теперь я хочу прочитать весь вывод прямо в строке для дальнейшей обработки. Я читал, что могу сделать это с помощью popen, но никогда не использовал объекты каналов.

Как мне это сделать?


person Lyndon White    schedule 26.02.2010    source источник
comment
Дубликаты: stackoverflow.com/search?q=%5Bpython%5D+subprocess+output, stackoverflow.com/ questions / 1180606 / Тем не менее, +1 за ясность и ясность, а также за постобработку. :)   -  person    schedule 26.02.2010


Ответы (5)


Функция os.popen просто возвращает объект в виде файла. Вы можете использовать это так:

import os

process = os.popen('gcc -E myHeader.h')
preprocessed = process.read()
process.close()

Как говорили другие, вы должны использовать subprocess.Popen. Он разработан как более безопасная версия os.popen. В документах Python есть раздел , в котором описывается, как переключить.

person Brian McKenna    schedule 26.02.2010

import subprocess

p = subprocess.popen('gcc -E myHeader.h'.split(),
                     stdout=subprocess.PIPE)
preprocessed, _ = p.communicate()

Строка preprocessed теперь имеет предварительно обработанный исходный код, который вам нужен - и вы использовали «правильный» (современный) способ оболочки для подпроцесса, а не старый, уже не очень понравившийся os.popen.

person Alex Martelli    schedule 26.02.2010
comment
Очень красивый пример. Есть ли способ разделить потоки stdout и stderr? - person smith324; 05.04.2011
comment
Теперь .split() - одна из вещей, которые происходят в оболочке и делают ее небезопасной в использовании. (Рассмотрим subprocess.open(cmd.split()) и случай, когда кто-то переходит в 'gcc "My Program.c"' вместо _4 _...) - person toolforger; 02.07.2019

вы должны использовать subprocess.Popen() есть множество примеров на SO

Как получить вывод из subprocess.Popen ()

person John La Rooy    schedule 26.02.2010
comment
Пожалуйста, включите выдержку из базы данных для защиты от гниения ссылок. - person SDsolar; 29.03.2018

os.popen () устарел, начиная с Python 2.6. Теперь вам следует использовать модуль subprocess: http://docs.python.org/2/library/subprocess.html#subprocess.Popen

import subprocess

command = "gcc -E myHeader.h"  # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)

#Launch the shell command:
output = process.communicate()

print output[0]

В конструкторе Popen, если shell имеет значение True, вы должны передавать команду в виде строки, а не последовательности. В противном случае просто разделите команду на список:

command = ["gcc", "-E", "myHeader.h"]  # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)

Если вам нужно прочитать также стандартную ошибку при инициализации Popen, вы можете установить для stderr значение subprocess.PIPE или subprocess.STDOUT:

import subprocess

command = "gcc -E myHeader.h"  # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

#Launch the shell command:
output, error = process.communicate()
person Paolo Rovelli    schedule 28.04.2013

Вот еще один подход, который фиксирует как обычный вывод, так и вывод ошибок:

com_str = 'uname -a'
command = subprocess.Popen([com_str], stdout=subprocess.PIPE, shell=True)
(output, error) = command.communicate()
print output

Linux 3.11.0-20-generic  Fri May 2 21:32:55 UTC 2014 GNU/Linux

и

com_str = 'id'
command = subprocess.Popen([com_str], stdout=subprocess.PIPE, shell=True)
(output, error) = command.communicate()
print output

uid=1000(myname) gid=1000(myGID) groups=1000(mygrp),0(root)
person SDsolar    schedule 29.03.2018