Hello everyone , I'm brother Chen ~
In the use of Python When writing some scripts , In some cases , We need to log in to the remote service frequently to execute a command , And return some results .
stay shell Environment , That's what we do .
$ sshpass -p ${passwd} ssh -p ${port} -l ${user} -o StrictHostKeyChecking=no xx.xx.xx.xx "ls -l"
And then you'll see , There's a lot of your output that you don't need , But some information that can't be lost ( Maybe there's a way , Please leave a message ), Like this
host: xx.xx.xx.xx, port: xx
Warning: Permanently added '[xx.xx.xx.xx]:xx' (RSA) to the list of known hosts.
Login failure: [Errno 1] This server is not registered to rmp platform, please confirm whether cdn server.
total 4
-rw-r--r-- 1 root root 239 Mar 30 2018 admin-openrc
For direct use shell command , To carry out an order , You can use pipes directly , Or redirect the standard output to a file to get the result of executing the command
If you use Python To do it , Usually we will be the first to , Think of using os.popen,os.system,commands,subprocess Wait for some command execution libraries to indirectly get .
But as far as I know , These libraries get output Not only standard output , There are also standard errors ( That is, the redundant information above )
So always be right output Data cleaning , Then organize and format , To get the data we want .
use subprocess for instance , Like this
import subprocess
ssh_cmd = "sshpass -p ${passwd} ssh -p 22 -l root -o StrictHostKeyChecking=no xx.xx.xx.xx 'ls -l'"
status, output = subprocess.getstatusoutput(ssh_cmd)
# Data cleaning , The formatted ones don't show
<code...>
Through the above words + Code display , You can feel it ssh Some of the pain points of landing
It hurts a little : Additional installation required sshpass( If you can't help it )
Pain point two : Too much interference information , Data cleaning 、 Formatting is quite cumbersome
Pain point three : The code implementation is not elegant enough ( It's a bit of dirt ), Poor readability
It hurts four :ssh Connections cannot be reused , A connection can only be executed once
Pain point five : The code can't be all platform , Only in Linux and OSX Upper use
To solve these problems , I searched the whole web about Python SSH The article , I really found two libraries
sh.ssh
Paramiko
First, let's introduce the first one ,sh.ssh
sh
It's a function call that allows you to do Linxu/OSX A library of system commands , Very easy to use , I have the opportunity to write an introduction about it .
$ python3 -m pip install sh
Only one of its functions is introduced today :ssh
Usually two machines visit each other , For convenience , You can set password free login , So you don't have to enter a password .
This code can realize the password free login , And execute our orders ls -l
from sh import ssh
output=ssh("[email protected]", "-p 22", "ls -l")
print(output)
But it's possible , We don't want to set up mutual trust , To make this code more generic , I assume we don't have a secret exemption , You can only log in with a password .
Here's the problem , To enter a password , You have to use interactive methods to input , stay Python How can we achieve this ?
original ssh Method to receive a _out
Parameters , This parameter can be a string , Represents the file path , It can also be a file object ( Or class file object ), It can also be a callback function , When there is standard output , Call to pass the output to this function .
This is easy to do .
I just need to recognize that there is password:
word , Just write my password into the standard input .
The complete code is as follows :
import sys
from sh import ssh
aggregated = ""
def ssh_interact(char, stdin):
global aggregated
sys.stdout.write(char.encode())
sys.stdout.flush()
aggregated += char
if aggregated.endswith("password: "):
stdin.put("you_password\n")
output=ssh("[email protected]", "-p 22", "ls -l",_tty_in=True, _out_bufsize=0, _out=ssh_interact)
print(output)
This is the official document (http://amoffat.github.io/sh/tutorials/interacting_with_processes.html?highlight=ssh) Some information for , Write a demo.
After trying to run , The discovery program will always be running , Never to return , Will not quit , Callback functions will never enter .
Check the source code through debugging , Still can't find the problem , So I went to Github I've searched it up and down , Originally in 2017 This problem has existed since , Up to now 2020 It hasn't been repaired yet , Seems to use sh.ssh
Not many people , So I was “ Questioning ” Now , Expect to get a reply .
The above question , It only appears when a password is required , If the machine mutual trust is set up, there is no problem .
To feel sh.ssh
The use effect of , I've set up a machine to trust each other , Then use the following code .
from sh import ssh
my_server=ssh.bake("[email protected]", "-p 22")
# It's equivalent to logging in and executing commands one at a time , Exit login after execution
print(my_server.ls())
# Can be found in sleep period , Manually log in to the server , Use top , Check how many terminals are currently connected
time.sleep(5)
# When the order is executed again , The number of landing terminals will be +1, After the execution , And will be -1
print(my_server.ifconfig())
Surprised to find the use of bake
This way, ,my_server.ls()
and my_server.ifconfig()
This seems to be through the same ssh Connect , Execute the order twice , But actually , You can be on a remote machine , perform top Command to see changes in connected terminals , Will first +1
Again -1
, Explain that the execution of two commands is realized through two connections .
So it seems , Use sh.ssh
It can solve the pain ( If the above problems can be solved )、 Pain point two 、 Pain point three .
But it still can't be reused ssh Connect , It's still inconvenient , It's not the best plan for me .
The most important thing is , sh
This module , Support only Linxu/OSX , stay Windows You have to use its brother Library - pbs
, Then I went to pypi Take a look at pbs, already “ In disrepair ”, No one's defending .
thus , I am from “ pawn ”, It's almost the last straw .
With the last glimmer of hope , I tried to use paramiko
This library , Finally in the paramiko
here , Find back what should have been Python The elegance of .
You can install it with the following command
$ python3 -m pip install paramiko
And then next , Just introduce some common ssh How to log in
Then you can refer to the following code , stay Linux/OSX Remote connection under the system
import paramiko
ssh = paramiko.SSHClient()
# Allow connection not in know_hosts Hosts in files
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Establishing a connection
ssh.connect("xx.xx.xx.xx", username="root", port=22, password="you_password")
# Use this connection to execute commands
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("ls -l")
# Get output
print(ssh_stdout.read())
# Close the connection
ssh.close()
Method 1 It's a traditional connection server 、 Carry out orders 、 An operation to close , Multiple operations need to be connected multiple times , Unable to reuse connection [ It hurts four ].
Sometimes you need to log in to the server to perform multiple operations , Such as executing orders 、 Upload / Download the file , Method 1 Can't achieve , Then you can use it transport Methods .
import paramiko
# Establishing a connection
trans = paramiko.Transport(("xx.xx.xx.xx", 22))
trans.connect(username="root", password="you_passwd")
# take sshclient Of transport Designated as above trans
ssh = paramiko.SSHClient()
ssh._transport = trans
# The rest is the same as above
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("ls -l")
print(ssh_stdout.read())
# Close the connection
trans.close()
import paramiko
# Designate local RSA Private key file
# If the password is set when the key pair is established ,password Password set for , If there is no need to specify password Parameters
pkey = paramiko.RSAKey.from_private_key_file('/home/you_username/.ssh/id_rsa', password='12345')
# Establishing a connection
ssh = paramiko.SSHClient()
ssh.connect(hostname='xx.xx.xx.xx',
port=22,
username='you_username',
pkey=pkey)
# Carry out orders
stdin, stdout, stderr = ssh.exec_command('ls -l')
# The result is put in stdout in , If there is a mistake, it will be put in stderr in
print(stdout.read())
# Close the connection
ssh.close()
import paramiko
# Designate local RSA Private key file
# If the password is set when the key pair is established ,password Password set for , If there is no need to specify password Parameters
pkey = paramiko.RSAKey.from_private_key_file('/home/you_username/.ssh/id_rsa', password='12345')
# Establishing a connection
trans = paramiko.Transport(('xx.xx.xx.xx', 22))
trans.connect(username='you_username', pkey=pkey)
# take sshclient Of transport Designated as above trans
ssh = paramiko.SSHClient()
ssh._transport = trans
# Carry out orders , Just like the traditional way
stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())
# Close the connection
trans.close()
The above four methods , It can help you to log in to the server remotely to execute commands , If you need to reuse connections : One connection executes multiple commands , have access to Method 2 and Method four
After use , Remember to close the connection .
meanwhile ,paramiko As ssh The perfect solution , It's very professional , It can also be used to achieve sftp File transfer .
import paramiko
# Instantiate a trans object # Instantiate a transport object
trans = paramiko.Transport(('xx.xx.xx.xx', 22))
# Establishing a connection
trans.connect(username='you_username', password='you_passwd')
# Instantiate a sftp object , Specify the channel to connect
sftp = paramiko.SFTPClient.from_transport(trans)
# Send a file
sftp.put(localpath='/tmp/11.txt', remotepath='/tmp/22.txt')
# Download the file
sftp.get(remotepath='/tmp/22.txt', localpath='/tmp/33.txt')
trans.close()
Come here ,Paramiko It's a complete victory , But there is still a pain point we didn't mention , It's multi platform , It's about Windows, Here's a good thing , A bad thing ,.
Good thing is :paramiko Support windows
The bad thing is : You need to do a lot of complicated preparation , You can google solve , But I suggest you give up , The pit is too deep .
Use paramiko When , There is one thing to note , This is also my own " Step on the pit " I found it later , In fact, I think this design is very good , If you don't have to wait for it to return data , The asynchronous effect can be realized directly , It's just for people who don't know the design , It's really an easy spot to fall into a pit
Is to carry out ssh.exec_command(cmd)
when , This command is not synchronous blocking .
For example, the following code , Execution time , You'll find that The script ends immediately and exits , Not waiting 5 s after , Again perform ssh.close()
import paramiko
trans = paramiko.Transport(("172.20.42.1", 57891))
trans.connect(username="root", password="youpassword")
ssh = paramiko.SSHClient()
ssh._transport = trans
stdin, stdout, stderr = ssh.exec_command("sleep 5;echo ok")
ssh.close()
But if it's like this , Add a line stdout.read(), paramiko You know , You need the result of this execution , Will be in read() To block .
import paramiko
trans = paramiko.Transport(("172.20.42.1", 57891))
trans.connect(username="root", password="youpassword")
ssh = paramiko.SSHClient()
ssh._transport = trans
stdin, stdout, stderr = ssh.exec_command("sleep 5;echo ok")
# Add a line read()
print(stdout.read())
ssh.close()
After some comparison , And some examples , It can be seen that Paramiko It's a major 、 It's easy ssh tool , Personally think that Paramiko Module is one of the necessary modules for operation and maintenance personnel , If you happen to need to be in Python In the code ssh Go to the remote server to get some information , Then I put Paramiko Recommended to you .
Last , Hope this article , Can help you .
https://github.com/paramiko/paramiko
http://docs.paramiko.org
https://www.liujiangblog.com/blog/15/
http://docs.paramiko.org/en/stable/
Guess you like
No, 50W Betrothal gifts , My girlfriend was forcibly dragged away , What am I gonna do?
20 Zhang let the boss praise the large visual screen , Attached source code template !