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

Как вы используете subprocess.check_output() в Python?

Я нашел документацию о subprocess.check_output(), но я не могу найти ее с аргументами, и документация не очень глубока. Я использую Python 3 (но пытаюсь запустить файл Python 2 через Python 3)

Я пытаюсь запустить эту команду: python py2.py -i test.txt

-i - позиционный аргумент для argparse, test.txt - это то, что -i, py2.py - это файл для запуска

Я пробовал много (нерабочих) вариантов, в том числе: py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])

py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])

4b9b3361

Ответ 1

Правильный ответ (используя Python 2.7 и более поздние check_output(), так как check_output() был введен check_output()):

py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])

Чтобы продемонстрировать, вот мои две программы:

py2.py:

import sys
print sys.argv

py3.py:

import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)

Запуск это:

$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"

Вот что не так с каждой из ваших версий:

py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])

Во-первых, str('python py2.py') - это то же самое, что и 'python py2.py' вы берете str и вызываете str для преобразования его в str. Это делает код сложнее для чтения, длиннее и даже медленнее, без каких-либо дополнительных преимуществ.

Более серьезно, python py2.py не может быть одним аргументом, если вы на самом деле не пытаетесь запустить программу, скажем, /usr/bin/python\ py2.py Который вы не; вы пытаетесь запустить, скажем, /usr/bin/python с первым аргументом py2.py Итак, вам нужно сделать их отдельными элементами в списке.

Ваша вторая версия исправляет это, но вам не хватает ' before test.txt'. Это должно дать вам SyntaxError, возможно, произносящую EOL while scanning string literal.

Между тем, я не уверен, как вы нашли документацию, но не смогли найти никаких примеров с аргументами. Самый первый пример:

>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'

Это вызывает команду "echo" с дополнительным аргументом "Hello World!" ,

Также:

-i - это позиционный аргумент для argparse, test.txt - это -i

Я уверен, что -i не позиционный аргумент, а необязательный аргумент. В противном случае вторая половина предложения не имеет смысла.

Ответ 2

Добавляя к тому, который указан @abarnert

Лучше всего поймать исключение

import subprocess
try:
    py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'],stderr= subprocess.STDOUT)  
    #print('py2 said:', py2output)
    print "here"
except subprocess.CalledProcessError as e:
    print "Calledprocerr"

этот stderr = subprocess.STDOUT предназначен для того, чтобы вы не получили ошибку filenotfound в stderr, которая не может быть обычно поймана в filenotfoundexception, иначе вы в конечном итоге получите

python: can't open file 'py2.py': [Errno 2] No such file or directory

Наверное, лучшим решением для этого может быть проверка того, существуют ли файлы/сценарии, а затем запустить файл/script

Ответ 3

Начиная с Python 3.5, subprocess.run() рекомендуется вместо subprocess.check_output():

>>> subprocess.run(['cat','/tmp/text.txt'], stdout=subprocess.PIPE).stdout
b'First line\nSecond line\n'

Начиная с Python 3.7, вместо вышеуказанного вы можете использовать параметр capture_output=true для захвата stdout и stderr:

>>> subprocess.run(['cat','/tmp/text.txt'], capture_output=True).stdout
b'First line\nSecond line\n'

Кроме того, вы можете использовать universal_newlines=True или его эквивалент, так как Python 3.7 text=True для работы с текстом вместо двоичного:

>>> stdout = subprocess.run(['cat', '/tmp/text.txt'], capture_output=True, text=True).stdout
>>> print(stdout)
First line
Second line

См. Subprocess.run() документация для получения дополнительной информации.

Ответ 4

Почему бы не мыслить нестандартно и использовать туалет, который должен быть быстрее



import subprocess
import re

def get_num_lines_in_file(filename):
    num_lines = 0
    op = subprocess.check_output(['wc','-l',filename])
    m  = re.search("^(\d+)",op)
    if m:
        num_lines = int(m.group(1))
    return num_lines

f = "/etc/hosts"
print ("{} has {} lines".format(f,get_num_lines_in_file(f)))

Дает: /etc/hosts имеет 5 строк