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

Почему этот вызов bash с python не работает?

Я немного борюсь с биткойнами. Когда я хочу получить некоторую информацию о локальной установке bitcoin, я просто запускаю bitcoin getinfo, и я получаю что-то вроде этого:

{
    "version" : 90100,
    "protocolversion" : 70002,
    "walletversion" : 60000,
    "balance" : 0.00767000,
    "blocks" : 306984,
    "timeoffset" : 0,
    "connections" : 61,
    "proxy" : "",
    "difficulty" : 13462580114.52533913,
    "testnet" : false,
    "keypoololdest" : 1394108331,
    "keypoolsize" : 101,
    "paytxfee" : 0.00000000,
    "errors" : ""
}

Теперь я хочу выполнить этот вызов из Python (прежде чем кто-нибудь это укажет, я знаю, что реализация Python для Bitcoin, я просто хочу учиться делать это сам). Поэтому я сначала попробовал выполнить простую команду ls следующим образом:

import subprocess
process = subprocess.Popen('ls', stdout=subprocess.PIPE)
output = process.communicate()[0]
print output

Это прекрасно работает, распечатывая список файлов и папок, как ожидалось. Итак, я сделал это:

import subprocess
process = subprocess.Popen('bitcoin getinfo', stdout=subprocess.PIPE)
output = process.communicate()[0]
print output

но это дает следующую ошибку:

Traceback (most recent call last):
  File "testCommandLineCommands.py", line 2, in <module>
    process = subprocess.Popen('bitcoin getinfo', stdout=subprocess.PIPE)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

и здесь я немного потерян. Кто-нибудь знает, что здесь не так? Все советы приветствуются!

[EDIT] Используя превосходные ответы ниже, я теперь сделал следующую функцию, которая может пригодиться и для других. Он принимает либо строку, либо итерацию с отдельными аргументами, и анализирует вывод, если он json:

def doCommandLineCommand(command):
    process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=isinstance(command, str))
    output = process.communicate()[0]
    try:
        return json.loads(output)
    except ValueError:
        return output
4b9b3361

Ответ 1

Либо используйте последовательность в аргументах:

process = subprocess.Popen(['bitcoin', 'getinfo'], stdout=subprocess.PIPE)

или установите для параметра shell значение True:

process = subprocess.Popen('bitcoin getinfo', stdout=subprocess.PIPE, shell=True)

Дополнительную информацию вы можете найти в документации:

args требуется для всех вызовов и должен быть строкой или последовательностью аргументов программы. Обычно предлагается последовательность аргументов, так как она позволяет модулю заботиться о любом требуемом экранировании и цитировании аргументов (например, разрешать пробелы в именах файлов). Если передать одну строку, либо оболочка должна быть True (см. Ниже), либо строка должна просто указывать исполняемую программу без указания каких-либо аргументов.

Ответ 2

используйте следующий код:

process = subprocess.Popen(['bitcoin', 'getinfo'], stdout=subprocess.PIPE)

вам не разрешено использовать пробелы для передачи параметров.