What Is the Simplest Way to Ssh Using Python

What is the simplest way to SSH using Python?

I haven't tried it, but this pysftp module might help, which in turn uses paramiko. I believe everything is client-side.

The interesting command is probably .execute() which executes an arbitrary command on the remote machine. (The module also features .get() and .put methods which allude more to its FTP character).

UPDATE:

I've re-written the answer after the blog post I originally linked to is not available anymore. Some of the comments that refer to the old version of this answer will now look weird.

Native SSH in Python

There's no native support for the SSH in Python.

All you can to is:

  • Implement the SSH/SFTP from a scratch by yourself. That's an insane task.

  • Run a command-line SFTP client (e.g. the OpenSSH sftp) from Python code.

  • Paramiko uses the LGPL license, so you might be able to take its source code and use it directly, without installing any module.

Perform commands over ssh with Python

I will refer you to paramiko

see this question

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute)

If you are using ssh keys, do:

k = paramiko.RSAKey.from_private_key_file(keyfilename)
# OR k = paramiko.DSSKey.from_private_key_file(keyfilename)

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=host, username=user, pkey=k)

connection to ssh via Python

Have you tried using paramiko?

import paramiko

ssh_client = paramiko.SSHClient()
ssh_client .connect(server, username=username, password=password)
stdin, stdout, stderr = ssh_client.exec_command(command)

How to make a ssh connection with python?

Notice that this doesn't work in Windows.

The module pxssh does exactly what you want:

For example, to run 'ls -l' and to print the output, you need to do something like that :

from pexpect import pxssh
s = pxssh.pxssh()
if not s.login ('localhost', 'myusername', 'mypassword'):
print "SSH session failed on login."
print str(s)
else:
print "SSH session login successful"
s.sendline ('ls -l')
s.prompt() # match the prompt
print s.before # print everything before the prompt.
s.logout()

Some links :

Pxssh docs : http://dsnra.jpl.nasa.gov/software/Python/site-packages/Contrib/pxssh.html

Pexpect (pxssh is based on pexpect) : http://pexpect.readthedocs.io/en/stable/

Using SSH in python

There are a number of ways to use SSH from within Python. The general approaches are:

  • Call the local ssh binary using subprocess.Popen() or similar (suitable only for gathering the results in batch)
  • Call and control the local ssh binary using pexpect or a similar pty (psuedo-TTY) process control mechanism (for spawning and interacting with a process in a terminal session in an automated manner)
  • Use a Python module/library, like Paramiko or Twisted conch, which implements SSH protocols (either directly in native Python, or by providing bindings to some underlying shared library ... .so or DLL).

SSHController is in the second of these broad categories. My own humble utility, classh is in the first category.

Your question suggests that you might be best served by exploring Paramiko because it sounds like you want to set local variable state based on the results from remote process execution. I'm guessing that you don't want any chance of conflating any sort of local terminal output or error messages with the remote command's results.

In other words it sounds like you want to use SSH as an API rather than ssh as a command utility. This is an essential distinction.

The ssh command tries to be as transparent as the UNIX (and analogous MS Windows, etc) environments allow. ssh opens a connection to the remote system and creates a number of channels over which remote job execution communicates. So the local ssh stdout will be from the remote commands' stdout and the local ssh stderr will be a mixture of the remote's stderr and any of the ssh command's own error messages (and other output, such as the debugging information you'd see from adding the -v, --verbose options to your ssh invocation). Similarly the ssh command's exit status will, normally, reflect the exit status from the remote shell. However it may also be the local ssh process' own exit code from a local error --- which, in my experience, seems to always be value 255. I know of no way that you could distinguish between a remote command's exit value of 255 vs. an "abend" (abnormal process end) from the local process --- and I suspect that there is not any portable, standard way to do so).

My point here is that using the ssh command from within your code will, necessarily, preclude you from separating the output from local processes (the ssh binary itself, and perhaps, depending on how you're executing it, a local shell for that) and those which emanated from the remote process (and perhaps the shell in which the intended remote process is running). ssh is not an API.

On the other hand if you use something like Paramiko then you establish a session over the SSH protocol and you can use, and re-use that to execute commands, transfer files, perform some other filesystem functions, and create tunnels.

In that case you create an SSHClient instance and call its .exec_command() method for each command you which to execute on the remote host. This is conceptually similar to making a local function call ... it will raise an exception if the command could not be executed for any reason ... and any results you get from its stdout or stderr cannot be conflated with possible output from any intermediary processes (such as the ssh binary ... which isn't being executed at all in this case).

That's why I'm recommending this approach. It sounds like you want to execute several separate commands on each remote target in a way that obviates the possible complications arising from running them all in a single call to the ssh utility and without the complications and performance overhead of making multiple calls to ssh. It sounds like your code will be much simpler and more robust if you can establish a session and use that as an API.



Related Topics



Leave a reply



Submit