Что эквивалентно обратным кавычкам в Ruby и Perl в Python? То есть в Ruby я могу это сделать:
foo = `cat /tmp/baz`
Как эквивалентный оператор выглядит в Python? Я пробовал, os.system("cat /tmp/baz")
но это приводит к стандартному результату и возвращает мне код ошибки этой операции.
Ответы:
output = os.popen('cat /tmp/baz').read()
источник
`...`
(захват stdout, передача stderr через) - с одним исключением: Ruby позволяет определять код выхода процесса через$?
постфактум; Насколько я могу судить, в Python вам придется использоватьsubprocess
для этого функции модуля.Самый гибкий способ - использовать
subprocess
модуль:import subprocess out = subprocess.run(["cat", "/tmp/baz"], capture_output=True) print("program output:", out)
capture_output
был представлен в Python 3.7, для более старых версийcheck_output()
вместо него можно использовать специальную функцию :out = subprocess.check_output(["cat", "/tmp/baz"])
Вы также можете вручную создать объект подпроцесса, если вам нужен мелкозернистый элемент управления:
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE) (out, err) = proc.communicate()
Все эти функции поддерживают параметры ключевого слова, чтобы настроить, как именно выполняется подпроцесс. Вы можете, например, использовать
shell=True
для выполнения программы через оболочку, если вам нужны такие вещи, как расширение имени файла*
, но это имеет ограничения .источник
subprocess.run()
(я не знаю, заслужено ли это), если вам не нужно поддерживать более ранние версии или если вам не нужна гибкость, обеспечиваемаяPopen()
.что правильно . Вы также можете использовать os.popen (), но там, где он доступен (Python 2.4+), обычно предпочтительнее.
Однако, в отличие от некоторых языков, которые поощряют это, обычно считается дурным тоном создавать подпроцесс, в котором вы можете выполнять ту же работу внутри языка. Он медленнее, менее надежен и зависит от платформы. Ваш пример был бы лучше:
foo= open('/tmp/baz').read()
эта:
? cat в каталоге выдает мне ошибку.
Если вам нужен список файлов:
import os foo= os.listdir('/tmp/baz')
Если вам нужно содержимое всех файлов в каталоге, например:
contents= [] for leaf in os.listdir('/tmp/baz'): path= os.path.join('/tmp/baz', leaf) if os.path.isfile(path): contents.append(open(path, 'rb').read()) foo= ''.join(contents)
или, если вы можете быть уверены, что там нет каталогов, вы можете поместить его в однострочник:
path= '/tmp/baz' foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))
источник
foo = subprocess.check_output(["cat", "/tmp/baz"])
источник
Начиная с Python 3.5 и далее рекомендуется использовать
subprocess.run
. Начиная с Python 3.7, чтобы получить такое же поведение, как вы описываете, вы должны использовать:cpe = subprocess.run("ls", shell=True, capture_output=True)
Это вернет
subprocess.CompletedProcess
объект. Вывод на stdout будет внутриcpe.stdout
, вывод на stderr будет внутриcpe.stderr
, которые оба будутbytes
объектами. Вы можете декодировать результат , чтобы получитьstr
объект с помощьюcpe.stdout.decode()
или получить пропусканиеtext=True
кsubprocess.run
:cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)
В последнем случае
cpe.stdout
иcpe.stderr
являются обоимиstr
объектами.источник
text=True
параметр, чтобы вернуть str вместо байтов.Самый простой способ - использовать пакет команд.
import commands commands.getoutput("whoami")
Вывод:
источник
import os foo = os.popen('cat /tmp/baz', 'r').read()
источник
я использую
Один из приведенных выше примеров:
import subprocess proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True) (out, err) = proc.communicate() print "program output:", out
Для меня это не удалось получить доступ к каталогу / tmp. Посмотрев на строку документа для подпроцесса, я заменил
с участием
и получил желаемое поведение расширения оболочки (а-ля Perl `prog arg`)
Некоторое время назад я перестал использовать python, потому что меня раздражала сложность выполнения эквивалента perl `cmd ...`. Я рад, что Python сделал это разумным.
источник
Если вы используете subprocess.Popen, не забудьте указать bufsize. Значение по умолчанию - 0, что означает «без буферизации», а не «выбрать разумное значение по умолчанию».
источник
Это не будет работать в python3, но в python2 вы можете расширить его
str
с помощью специального__repr__
метода, который вызывает вашу команду оболочки и возвращает ее следующим образом:#!/usr/bin/env python import os class Command(str): """Call system commands""" def __repr__(cmd): return os.popen(cmd).read()
Что вы можете использовать как
#!/usr/bin/env python from command import Command who_i_am = `Command('whoami')` # Or predeclare your shell command strings whoami = Command('whoami') who_i_am = `whoami`
источник
repr()
Оператор
backtick
(`) был удален вPython 3
. Это до степени смешения похоже на одинарную кавычку, и ее сложно набрать на некоторых клавиатурах. Вместоbacktick
используйте эквивалентную встроенную функциюrepr()
.источник