Execute a command on Remote Machine in Python
Question: I am writing a program in python on Ubuntu, to execute a command `ls -l` on
RaspberryPi, connect with Network.

Can anybody guide me on how do I do that?


Answer: Sure, there are several ways to do it!

Let's say you've got a Raspberry Pi on a `raspberry.lan` host and your
username is `irfan`.

# subprocess

It's the default Python library that runs commands.  
You can make it run `ssh` and do whatever you need on a remote server.

scrat [has it covered in his
answer](http://stackoverflow.com/a/28413657/974317). You definitely should do
this if you don't want to use any third-party libraries.

You can also automate the password/passphrase entering using
[`pexpect`](http://pexpect.readthedocs.org/en/latest/).

# paramiko

[`paramiko`](https://github.com/paramiko/paramiko) is a third-party library
that adds SSH-protocol support, so it can work like an SSH-client.

The example code that would connect to the server, execute and grab the
results of the `ls -l` command would look like that:

    
    
    import paramiko
    
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect('raspberry.lan', username='irfan', password='my_strong_password')
    
    stdin, stdout, stderr = client.exec_command('ls -l')
    
    for line in stdout:
        print line.strip('\n')
    
    client.close()
    

# fabric

You can also achieve it using
[`fabric`](http://docs.fabfile.org/en/1.10/tutorial.html).  
Fabric is a deployment tool which executes various commands on remote servers.

It's often used to run stuff on a remote server, so you could easily put your
latest version of the web application, restart a web-server and whatnot with a
single command. Actually, you can run the same command on multiple servers,
which is awesome!

Though it was made as a deploying and remote management tool, you still can
use it to execute basic commands.

    
    
    # fabfile.py
    from fabric.api import *
    
    def list_files():
        with cd('/'):  # change the directory to '/'
            result = run('ls -l')  # run a 'ls -l' command
            # you can do something with the result here,
            # though it will still be displayed in fabric itself.
    

It's like typing `cd /` and `ls -l` in the remote server, so you'll get the
list of directories in your root folder.

Then run in the shell:

    
    
    fab list_files
    

It will prompt for an server address:

    
    
    No hosts found. Please specify (single) host string for connection: irfan@raspberry.lan
    

* * *

**A quick note** : You can also assign a username and a host right in a `fab`
command:

    
    
    fab list_files -U irfan -H raspberry.lan
    

Or you could put a host into the `env.hosts` variable in your fabfile. [Here's
how to do it](http://docs.fabfile.org/en/1.10/tutorial.html#defining-
connections-beforehand).

* * *

Then you'll be prompted for a SSH password:

    
    
    [irfan@raspberry.lan] run: ls -l
    [irfan@raspberry.lan] Login password for 'irfan':
    

And then the command will be ran successfully.

    
    
    [irfan@raspberry.lan] out: total 84
    [irfan@raspberry.lan] out: drwxr-xr-x   2 root root  4096 Feb  9 05:54 bin
    [irfan@raspberry.lan] out: drwxr-xr-x   3 root root  4096 Dec 19 08:19 boot
    ...
    

