Эквивалент Баш обратные кавычки в Python


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

foo = `cat /tmp/baz`

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

10 75

10 ответов:

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

самый гибкий способ-это использовать subprocess модуль:

import subprocess

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

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

СТГ прав. Вы также можете использовать ОС.popen (), но там, где это возможно (Python 2.4+) подпроцесс, как правило, предпочтительнее.

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

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

eta:

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

? кошка в каталоге получает мне сообщение об ошибке.

если вам нужен список файлов:

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

это вернет a

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

import commands

commands.getoutput("whoami")

выход:

'bganesan'

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"

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

печать подпроцесса.Popen ("ls-ld /tmp/v*", stdout=подпроцесс.Труба, оболочка=True).communicate()[0]


Я перестал использовать python некоторое время назад, потому что меня раздражала сложность выполнения эквивалента perl `cmd ...'. Я рад, что Python сделал это разумным.

Если вы используете подпроцесса.Попен, не забудьте указать bufsize. Значение по умолчанию равно 0, что означает "unbuffered", а не "Выберите разумное значение по умолчанию".

это не будет работать в 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`