Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I am messing around with Bitcoins a bit. When I want to get some info about the local bitcoin install, I simply run bitcoin getinfo and I get something like this:

{
    "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" : ""
}

I now want to do this call from within Python (before anyone points it out; I know there are Python implementations for Bitcoin, I just want to learn doing it myself). So I first tried executing a simple ls command like this:

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

This works fine, printing out the list of files and folders as expected. So then I did this:

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

but this gives the following error:

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

and here I'm kinda lost. Does anybody know what's wrong here? All tips are welcome!

[EDIT] Using the excellent answers below I now made the following function, which might come in handy for others as well. It takes either a string, or an iterable with separate arguments and parses the output if it is 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
share|improve this question
    
Are you sure your script really sees the "bitcoin" executable? If it is in /usr/bin or equivalent, try giving the full path. ls is ashell command and accessible everywhere, that is why it works. – DrV Jun 21 '14 at 10:59
up vote 9 down vote accepted

Either use a sequence in arguments:

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

or set the shell parameter to True:

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

You can find more information in the documentation:

args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.

share|improve this answer
    
The first option you give still gives me an error saying File "/usr/lib/python2.7/subprocess.py", line 659, in __init__ raise TypeError("bufsize must be an integer"), but the second option indeed works! Awesome! Any idea why I get the error with the first option though? – kramer65 Jun 21 '14 at 11:12
1  
@kramer65 Are you sure you use ['bitcoin', 'getinfo'] and not 'bitcoin', 'getinfo'? Brackets are required. – Gergo Erdosi Jun 21 '14 at 11:15
    
You were right, thanks for the elaborate answer! – kramer65 Jun 21 '14 at 11:25

use the following code:

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

you are not allowed to use spaces for passing parameters.

share|improve this answer
    
Thanks for the suggestion. I tried it but I then get an error saying: File "/usr/lib/python2.7/subprocess.py", line 659, in __init__ raise TypeError("bufsize must be an integer"). Any idea why this also fails? – kramer65 Jun 21 '14 at 11:11
1  
@kramer65 I think you have forgotten [] for passing args – user1922137 Jun 21 '14 at 11:15
1  
Absolutely true! Thanks! – kramer65 Jun 21 '14 at 11:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.