可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How can I simply SSH to a remote server from a local Python (3.0) script, supply a login/password, execute a command and print the output to the Python console?
I would rather not use any large external library or install anything on the remote server.
回答1:
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.
回答2:
You can code it yourself using Paramiko, as suggested above. Alternatively, you can look into Fabric, a python application for doing all the things you asked about:
Fabric is a Python library and
command-line tool designed to
streamline deploying applications or
performing system administration tasks
via the SSH protocol. It provides
tools for running arbitrary shell
commands (either as a normal login
user, or via sudo), uploading and
downloading files, and so forth.
I think this fits your needs. It is also not a large library and requires no server installation, although it does have dependencies on paramiko and pycrypt that require installation on the client.
The app used to be here. It can now be found here.
* The official, canonical repository is git.fabfile.org
* The official Github mirror is GitHub/bitprophet/fabric
There are several good articles on it, though you should be careful because it has changed in the last six months:
Deploying Django with Fabric
Tools of the Modern Python Hacker: Virtualenv, Fabric and Pip
Simple & Easy Deployment with Fabric and Virtualenv
Later: Fabric no longer requires paramiko to install:
$ pip install fabric
Downloading/unpacking fabric
Downloading Fabric-1.4.2.tar.gz (182Kb): 182Kb downloaded
Running setup.py egg_info for package fabric
warning: no previously-included files matching '*' found under directory 'docs/_build'
warning: no files found matching 'fabfile.py'
Downloading/unpacking ssh>=1.7.14 (from fabric)
Downloading ssh-1.7.14.tar.gz (794Kb): 794Kb downloaded
Running setup.py egg_info for package ssh
Downloading/unpacking pycrypto>=2.1,!=2.4 (from ssh>=1.7.14->fabric)
Downloading pycrypto-2.6.tar.gz (443Kb): 443Kb downloaded
Running setup.py egg_info for package pycrypto
Installing collected packages: fabric, ssh, pycrypto
Running setup.py install for fabric
warning: no previously-included files matching '*' found under directory 'docs/_build'
warning: no files found matching 'fabfile.py'
Installing fab script to /home/hbrown/.virtualenvs/fabric-test/bin
Running setup.py install for ssh
Running setup.py install for pycrypto
...
Successfully installed fabric ssh pycrypto
Cleaning up...
This is mostly cosmetic, however: ssh is a fork of paramiko, the maintainer for both libraries is the same (Jeff Forcier, also the author of Fabric), and the maintainer has plans to reunite paramiko and ssh under the name paramiko. (This correction via pbanka.)
回答3:
If you want to avoid any extra modules, you can use the subprocess module to run
ssh [host] [command]
and capture the output.
Try something like:
process = subprocess.Popen("ssh example.com ls", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output,stderr = process.communicate()
status = process.poll()
print output
To deal with usernames and passwords, you can use subprocess to interact with the ssh process, or you could install a public key on the server to avoid the password prompt.
回答4:
I have written Python bindings for libssh2. Libssh2 is a client-side library implementing the SSH2 protocol.
import socket
import libssh2
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('exmaple.com', 22))
session = libssh2.Session()
session.startup(sock)
session.userauth_password('john', '******')
channel = session.channel()
channel.execute('ls -l')
print channel.read(1024)
回答5:
Your definition of "simplest" is important here - simple code means using a module (though "large external library" is an exaggeration).
I believe the most up-to-date (actively developed) module is paramiko. It comes with demo scripts in the download, and has detailed online API documentation. You could also try PxSSH, which is contained in pexpect. There's a short sample along with the documentation at the first link.
Again with respect to simplicity, note that good error-detection is always going to make your code look more complex, but you should be able to reuse a lot of code from the sample scripts then forget about it.
回答6:
Like hughdbrown, I like Fabric. Please notice that while it implement its own declarative scripting (for making deploys and the such) it can also be imported as a Python module and used on your programs without having to write a Fabric script.
Fabric has a new maintainer and is in the process of being rewriten; that means that most tutorials you'll (currently) find on the web will not work with the current version. Also, Google still shows the old Fabric page as the first result.
For up to date documentation you can check: http://docs.fabfile.org
回答7:
I found paramiko to be a bit too low-level, and Fabric not especially well-suited to being used as a library, so I put together my own library called spur that uses paramiko to implement a slightly nicer interface:
import spur
shell = spur.SshShell(hostname="localhost", username="bob", password="password1")
result = shell.run(["echo", "-n", "hello"])
print result.output # prints hello
You can also choose to print the output of the program as it's running, which is useful if you want to see the output of long-running commands before it exits:
result = shell.run(["echo", "-n", "hello"], stdout=sys.stdout)
回答8:
For benefit of those who reach here googling for python ssh sample.
The original question and answer are almost a decode old now.
It seems that the paramiko has gain a bit of functionalities (Ok. I'll admit - pure guessing here - I'm new to Python) and you can create ssh client directly with paramiko.
import base64
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.1.1', username='user', password='password')
stdin, stdout, stderr = client.exec_command('cat /proc/meminfo')
for line in stdout:
print('... ' + line.strip('\n'))
client.close()
This code was adapted from demo of https://github.com/paramiko/paramiko
It works for me.
回答9:
This worked for me
import subprocess
import sys
HOST="IP"
COMMAND="ifconfig"
def passwordless_ssh(HOST):
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if result == []:
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
return "error"
else:
return result
回答10:
Have a look at spurplus, a wrapper around spur and paramiko that we developed to manage remote machines and perform file operations.
Spurplus provides a check_output()
function out-of-the-box:
import spurplus
with spurplus.connect_with_retries(
hostname='some-machine.example.com', username='devop') as shell:
out = shell.check_output(['/path/to/the/command', '--some_argument'])
print(out)