Вопрос

Каков эквивалент обратных ссылок, найденных в Ruby и Perl, в Python?То есть, в Ruby я могу это сделать:

foo = `cat /tmp/baz`

Как выглядит эквивалентный оператор в Python?Я пытался os.system("cat /tmp/baz") но это приводит результат к стандартному результату и возвращает мне код ошибки этой операции.

Это было полезно?

Решение

output = os.popen('cat /tmp/baz').read()

Другие советы

Самый гибкий способ - использовать подпроцесс модуль:

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 для выполнения программы через оболочку, если вам нужны такие вещи, как расширения имен файлов в * , но они поставляются с ограничения .

sth прав.Вы также можете использовать os.popen(), но там, где доступен подпроцесс (Python 2.4+), как правило, предпочтительнее.

Однако, в отличие от некоторых языков, которые поощряют это, обычно считается дурным тоном создавать подпроцесс, в котором вы можете выполнять ту же работу внутри языка.Это медленнее, менее надежно и зависит от платформы.Ваш пример был бы лучше использовать как:

foo= open('/tmp/baz').read()

eta:

baz - это каталог, и я пытаюсь получить содержимое всех файлов в этом каталоге

?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 . Чтобы получить то же поведение, которое вы описываете, вы должны использовать:

output = subprocess.run("ls", shell=True, stdout=subprocess.PIPE).stdout

Это вернет объект bytes . Возможно, вы захотите добавить .decode (" ascii ") или .decode (" utf-8 ") в конец, чтобы получить str .

Самый простой способ - это использовать пакет команд.

import commands

commands.getoutput("whoami")

Выходной сигнал:

"бганесан"

import os
foo = os.popen('cat /tmp/baz', 'r').read()

Я использую

  

(6: 0) $ python --version   Python 2.7.1

Один из приведенных выше примеров:

import subprocess
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

Для меня это не удалось получить доступ к каталогу / tmp. Посмотрев строку документации для подпроцесса, я заменил

  

[" prog " ;, " arg "]

с

  

" prog arg "

и получил желаемое поведение расширения оболочки (а-ля Perl `prog arg`)

  

print subprocess.Popen (< ls -ld / tmp / v * " ;, stdout = subprocess.PIPE, shell = True) .communicate () [0]

<Ч>

Некоторое время назад я прекратил использовать 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`

Оператор backtick (`) был удален в Python 3 . Это похоже на одиночную кавычку и трудно вводить на некоторых клавиатурах. Вместо backtick используйте эквивалентную встроенную функцию <код> магнезии () .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top