ShutIt:一个基于Python的shell自动化框架

开发 后端 自动化
本文通过实例简单介绍了ShutIt这个基于Python的自动化框架的使用方法。

[[194837]]

译者注:本文通过实例简单介绍了ShutIt这个基于Python的自动化框架的使用方法。除了pexpect,我们又多了这个选择。以下是译文。

ShutIt是一个易于使用的基于shell的自动化框架。它对基于python的expect库(pexpect)进行了包装。你可以把它看作是“没有痛点的expect”。它可以通过pip进行安装。

Hello World

让我们从最简单的例子开始吧。创建一个名为example.py的文件:

import shutit   
 
session = shutit.create_session('bash')   
 
session.send('echo Hello World', echo=True 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

运行这个文件:

python example.py 
  • 1.

输出:

python example.py 
 
echo "Hello World" 
 
echo "Hello World" 
 
Hello World 
 
Ians-MacBook-Air.local:ORIGIN_ENV:RhuebR2T#  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

“send”函数的***个参数是要运行的命令。“echo”的参数将会输出到终端上。默认情况下,ShutIt是静默的。

登录服务器

如果你要登陆一台服务器并执行服务器上的命令。可以将example.py改为:

import shutit 
 
session = shutit.create_session('bash'
 
session.login('ssh you@example.com'user='you'password='mypassword'
 
session.send('hostname', echo=True
 
session.logout()  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

程序将登录到这台服务器上,并输出主机名。

hostname   
 
hostname   
 
example.com   
 
example.com:cgoIsdVv:heDa77HB#  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

显然,这很不安全!你可以这样运行:

import shutit 
 
session = shutit.create_session('bash'
 
password = session.get_input('', ispass=True
 
session.login('ssh you@example.com'user='you'password=password
 
session.send('hostname', echo=True
 
session.logout()  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

它会让你输入密码:

Input Secret: 
 
hostname 
 
hostname 
 
example.com 
 
example.com:cgoIsdVv:heDa77HB#  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

同样的,“login”方法在登录后改变了提示符。你给了ShutIt一个登录命令,并附带用户名和密码(如果需要的话),然后,ShutIt会完成剩余的事情。

“logout”负责终止“login”,并向屏幕输出发生的任何变化。

登录到多台服务器

假设你有一个集群包含两台服务器,并希望同时登录到这两个服务器上去。则只需要创建两个会话,并运行类似的login和send命令:

import shutit 
 
session1 = shutit.create_session('bash'
 
session2 = shutit.create_session('bash'
 
password1 = session1.get_input('Password for server1', ispass=True
 
password2 = session2.get_input('Password for server2', ispass=True
 
session1.login('ssh you@one.example.com'user='you'password=password1) 
 
session2.login('ssh you@two.example.com'user='you'password=password2) 
 
session1.send('hostname', echo=True
 
session2.send('hostname', echo=True
 
session1.logout() 
 
session2.logout()  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

将输出这样的结果:

$ python example.py 
 
Password for server1 
 
Input Secret: 
 
Password for server2 
 
Input Secret: 
 
hostname 
 
hostname 
 
one.example.com 
 
one.example.com:Fnh2pyFj:qkrsmUNs# hostname 
 
hostname 
 
two.example.com 
 
two.example.com:Gl2lldEo:D3FavQjA#  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

实例:监控多台服务器

我们可以通过添加一些代码逻辑来检查命令的输出,从而将上述代码变成一个简单的监控工具:

import shutit 
 
capacity_command="""df / | awk '{print $5}' | tail -1 | sed s/[^0-9]//""" 
 
session1 = shutit.create_session('bash'
 
session2 = shutit.create_session('bash'
 
password1 = session.get_input('Password for server1', ispass=True
 
password2 = session.get_input('Password for server2', ispass=True
 
session1.login('ssh you@one.example.com'user='you'password=password1) 
 
session2.login('ssh you@two.example.com'user='you'password=password2) 
 
capacity = session1.send_and_get_output(capacity_command) 
 
if int(capacity) < 10: 
 
print('RUNNING OUT OF SPACE ON server1!'
 
capacity = session2.send_and_get_output(capacity_command) 
 
if int(capacity) < 10: 
 
print('RUNNING OUT OF SPACE ON server2!'
 
session1.logout() 
 
session2.logout()  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.

在这里,我们用了“sendandget_output”方法来获取capacity_command命令的输出。

还有很多更加优雅的方法可以完成上面的操作,但这取决于你想要Python有多聪明。

更复杂的IO – Expecting

假设你需要跟一个命令行程序进行交互,并且要实现自动化操作。在这里,我们使用telnet来举一个简单的例子:

import shutit 
 
session = shutit.create_session('bash'
 
session.send('telnet', expect='elnet>', echo=True
 
session.send('open google.com 80', expect='scape character', echo=True
 
session.send('GET /', echo=True, check_exit=False
 
session.logout()  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

注意“expect”的参数。你只需要给出telnet提示符的一个子集来进行匹配。

注意“check_exit”的参数,后面我们会讲到这个参数的。上面这段代码将输出:

$ python example.py 
 
telnet 
 
telnet> open google.com 80 
 
Trying 216.58.214.14... 
 
Connected to google.com. 
 
Escape character is '^]'
 
GET / 
 
HTTP/1.0 302 Found 
 
Cache-Control: private 
 
Content-Type: text/html; charset=UTF-8 
 
Referrer-Policy: no-referrer 
 
Location: http://www.google.co.uk/?gfe_rd=cr&ei=huczWcj3GfTW8gfq0paQDA 
 
Content-Length: 261 
 
Date: Sun, 04 Jun 2017 10:57:10 GMT 
 
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"
 
<TITLE>302 Moved</TITLE></HEAD><BODY> 
 
<H1>302 Moved</H1> 
 
The document has moved 
 
<A HREF="http://www.google.co.uk/?gfe_rd=cr&ei=huczWcj3GfTW8gfq0paQDA"
 
here 
 
</A>. 
 
</BODY></HTML> 
 
Connection closed by foreign host.  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.

现在回到“checkexit = false”上来。由于telnet命令会返回一个错误的退出码(1),我们不想让脚本执行失败,这里的“checkexit = false”能让ShutIt知道你并不关注这个退出码。

如果你没有传入这个参数,ShutIt会给你一个交互式的提示,如果你有终端接入的话。这被称为“暂停点”。

暂停点

你可以随便在什么时候通过调用以下方法来设置一个“暂停点”。

[...] 
 
session.pause_point('This is a pause point'
 
[...]  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

当脚本运行到暂停点时,同时按下“Ctrl”和“]”,则可以让脚本继续执行。这对于调试非常有用:添加一个暂停点,看看周围,然后继续。试试这个:

import shutit 
 
session = shutit.create_session('bash'
 
session.pause_point('Have a look around!'
 
session.send('echo "Did you enjoy your pause point?"', echo=True 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

程序输出:

$ python example.py 
 
Have a look around! 
 
Ians-Air.home:ORIGIN_ENV:I00LA1Mq# bash 
 
imiell@Ians-Air:/space/git/shutit ⑂ master +  
 
CTRL-] caught, continuing with run... 
 
2017-06-05 15:12:33,577 INFO: Sending: exit 
 
2017-06-05 15:12:33,633 INFO: Output (squashed): exitexitIans-Air.home:ORIGIN_ENV:I00LA1Mq# [...] 
 
echo "Did you enjoy your pause point?" 
 
echo "Did you enjoy your pause point?" 
 
Did you enjoy your pause point? 
 
Ians-Air.home:ORIGIN_ENV:I00LA1Mq#  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

更复杂的IO – Backgrounding

回到我们上面的“监控多台服务器”的例子上来。想象一下,我们要在每台服务器上运行一个长时间运行的任务。默认情况下,ShutIt会持续运行很长时间。但是我们可以在后台运行任务来加快ShutIt的运行速度。

在这里,你可以使用简单的命令“sleep 60”来尝试一个例子。

import shutit 
 
import time 
 
long_command="""sleep 60""" 
 
session1 = shutit.create_session('bash'
 
session2 = shutit.create_session('bash'
 
password1 = session1.get_input('Password for server1', ispass=True
 
password2 = session2.get_input('Password for server2', ispass=True
 
session1.login('ssh you@one.example.com'user='you'password=password1) 
 
session2.login('ssh you@two.example.com'user='you'password=password2) 
 
start = time.time() 
 
session1.send(long_command, background=True
 
session2.send(long_command, background=True
 
print('That took: ' + str(time.time() - start) + ' seconds to fire'
 
session1.wait() 
 
session2.wait() 
 
print('That took: ' + str(time.time() - start) + ' seconds to complete') 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.

我的笔记本电脑说,运行这两个命令只需花费0.5秒,而脚本在一分钟以后才运行结束(使用了’wait’方法)。

虽然这个例子看起来是微不足道的,但是想像一下,如果你有数百台这样的服务器需要管理,那么你可以看到这几行代码和一个python import所带来的强大的力量。

更多信息

ShutIt可以做很多事。更多信息,请参阅:

  • ShutIt (https://ianmiell.github.io/shutit/)
  • GitHub (https://github.com/ianmiell/shutit/blob/master/README.md) 
责任编辑:庞桂玉 来源: Python开发者
相关推荐

2019-08-14 10:49:20

Python编程语言代码

2019-04-22 09:00:00

Python框架自动化测试

2023-07-24 10:58:51

CIO自动化

2021-06-02 09:32:46

Angular自动化功能请求

2021-04-01 10:51:44

机器人人工智能编程

2020-11-06 08:43:21

AIOps运维DevOps

2023-12-21 11:12:31

Node.js.NET开源库

2022-04-11 15:34:29

机器学习AutoML开源

2024-05-13 16:29:56

Python自动化

2025-01-08 11:00:00

AIshell开源

2024-11-13 13:14:38

2018-12-10 08:10:39

2017-11-27 15:17:24

PythonMonkey脚本

2020-04-28 09:00:00

测试测试自动化

2024-08-16 21:51:42

2022-02-17 13:03:28

Python脚本代码

2024-06-21 10:46:44

2022-02-17 10:37:16

自动化开发团队预测

2021-02-03 09:04:11

解密Spring配置

2023-02-11 21:14:58

自动化测试框架
点赞
收藏

51CTO技术栈公众号