|
如果现在需要在 Linux 服务器上执行一系列命令(比如搭建 LNMP 环境)我应该会第一时间想到想办法写个 Shell 脚本,然后扔上去执行以下看看结果。4 s( ^& P* c/ y
然而一贯懒惰的我并不想这么去执行 Shell 和一些重复命令。所以俺寻思可以有个方法本地直接在服务器端执行脚本,寻思生异端,这时候有某大技霸告诉我有个叫 paramiko 的 Python 库,从此开启我新世界的大门。
对于 paramiko 安装直接 pip 或者 PyCharm 这里就不多说了,如果看到这里你觉得自己不怎么了解python语法的也不必担心,你完全可以用 paramiko 单纯的执行 Shell 命令查看结果和上传下载文件,省去重复的工作。 paramiko 实现了 SSHv2 协议(底层使用 cryptography ),包含两个核心组件:SSHClient 和 SFTPClient 。SSHClient 是对 SSH 会话的封装,用于执行远程命令,SFTPClient 是对 SFTP 客户端的封装,用以实现远程文件操作。 这里先举两个列子你应该就明白怎么用了,终于开始正片了。
SSHClient 的列子: - # -*- coding: utf-8 -*-
6 \5 n; o. Q8 N - import paramiko
' B1 ?, |* m; d/ ^- s. C3 g) n/ D - client = paramiko.SSHClient()# 实例化SSHClient7 X$ h; V8 ]2 R6 x# g7 i% Q2 o
- client.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不再本地know_hosts文件中记录的主机将无法连接
% W2 T% i0 d& x; |/ M - ) e2 {/ S, f6 Q; w6 [9 s
- client.connect(hostname='192.168.23.134', port=22, username='ftoz', password='123456')# 连接SSH服务端,以用户名和密码进行认证" `* u; A! ?, T# W5 X
1 ~$ j( C4 z) H+ A/ R+ \- # 打开一个Channel并执行命令* }6 f( `% W6 A1 e; ]6 p6 E
- stdin, stdout, stderr = client.exec_command('ls') # stdout 为正确输出,stderr为错误输出,同时是有1个变量有值
. D: o2 c; F P j( j
. m/ V! E+ Y2 h! D5 \- # 打印执行结果# j0 G6 R9 E# ~
- print(stdout.read().decode('utf-8'))( n7 k! K4 N' K( q u7 e# ^" \
* J7 O ` }, ~( o2 ^- # 关闭SSHClient
7 }. x* Z8 v: x4 {2 ~5 |# ^ - client.close()
复制代码 " o# G! M5 d) r0 L7 S y
输出:
! q! M5 h" V- w& J W- U2 kimage
3 U Z2 O \( x Q这里说明一下: - client = paramiko.SSHClient(),
/ d1 B. G& u5 f' O3 B' B6 N - client.set_missing_host_key_policy(paramiko.AutoAddPolicy())你可以理解为固定姿势。
0 g1 |0 Y5 H3 U. t - client.connect(hostname='192.168.1.105', port=22, username='ftoz',password='123456')这里就是你的linux变量依次为地址、端口(总共65535个端口,不过ssh默认是22端口)、登录名、密码。2 u- u) K9 g" {2 T. M
- stdin, stdout, stderr = client.exec_command('df -h ') 这里就是核心你需要做的shell命令,这三个变量不用按照这种姿势,你可以随意,不过按照顺序你知道里面装的什么数据就行(重点在输出和错误)。 @( W! W! f3 T1 \7 u) O
* S8 g. b0 p; `/ z- connect():这个是实现远程服务器连接和认证的,参数有:
2 c( o7 Z+ Q2 j8 Y% d9 \) _ - hostname 连接的目标主机
4 ]! H# G' ^; v j( h - port=SSH_PORT 指定端口
. K. ^5 I! j: L - username=None 验证的用户名
: }# r, L; g$ n; i6 E- R, Z - password=None 验证的用户密码! T4 J" B/ R% X8 l
- pkey=None 私钥方式用于身份验证
% K" l/ O0 Z9 m; o- { - key_filename=None 一个文件名或文件列表,指定私钥文件: _! g! q8 i* G. t8 F
- timeout=None 可选的tcp连接超时时间" t9 ~/ @: l$ k% P
- allow_agent=True, 是否允许连接到ssh代理,默认为True 允许7 G. B* |1 M! F. M# H8 Y
- look_for_keys=True 是否在~/.ssh中搜索私钥文件,默认为True 允许- d. G: L' ]! R: g: [. ]
- compress=False, 是否打开压缩。# b' l* N9 n. i1 y, T
- 4 P, |; x- t2 _) K& s* ^
- set_missing_host_key_policy():这个是设置远程服务器没有在know_hosts文件中记录时的应对策略。(可以理解为避免报错),参数有:2 o! T7 k- W# l' c. L; g W
- AutoAddPolicy 自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
& D/ C! D2 W, l3 s6 w - WarningPolicy 用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接( ~2 ~6 s: o$ z# J" y
- RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
/ |/ V. i; Q' C1 R5 F - exec_command():这是写你需要执行的命令的
复制代码 . g& p. J# Z3 o0 O! I" h4 m! K
接下来你就可以拿出输出做一些该干嘛(ke)干嘛(pa)的事情了,这里先举这个简单的列子。 SFTPClient 常用方法: - <font style="background-color:rgb(255, 255, 255)"><font color="black" face="Tahoma">t = paramiko.Transport(('192.168.23.134', 22))# 获取Transport实例
0 E4 f n' G% G {/ L8 I7 u" S - t.connect(username='ftoz', password='123456')# 连接SSH服务端,使用password) Z+ i- q5 \9 T: Q4 z
- sftp = paramiko.SFTPClient.from_transport(t)% L! G5 a; V) P
- sftp.put("F:\S12312.txt","/home/ftoz/zxc12312.txt")#执行上传动作
9 l; g$ i# I1 ?, @8 y3 Y) l! r) ` - sftp.get("/home/ftoz/zxc12312.txt", "F:\S12312.txt")#执行下载动作
; I" s' u9 |8 W! v - t.close()</font></font>
. K" a+ b, k! x! s
复制代码SFTPCLient 作为一个 sftp 的客户端对象,根据 ssh 传输协议的 sftp 会话,实现远程文件操作,如上传、下载、权限、状态 - from_transport(cls,t) 创建一个已连通的SFTP客户端通道3 b- a6 `& f% b& ~* L0 I* D
- put(localpath, remotepath, callback=None, confirm=True) 将本地文件上传到服务器 参数confirm:是否调用stat()方法检查文件状态,返回ls -l的结果
4 @9 l. b: S6 k" [+ n4 B# C+ B - get(remotepath, localpath, callback=None) 从服务器下载文件到本地& a" M- W7 U: S% ~5 k ^7 g
- mkdir() 在服务器上创建目录
$ k' ], ~ }5 i" h - remove() 在服务器上删除目录: b2 ]" ^+ E4 X3 ~. C# E% e6 q: }
- rename() 在服务器上重命名目录
: @) U+ `% k R. O" S( D - stat() 查看服务器文件状态
$ P0 k0 m0 V9 s3 m( m$ H* u - listdir() 列出服务器目录下的文件
复制代码 % u) h$ B/ ?3 F
9 ]: R0 H5 h. [$ y
最后养成随关闭的好习惯 client.close()。 ' r: ]) P' n. {6 [ h; B* B
|