社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

Python开发者 • 6 年前 • 557 次点击  

(点击上方蓝字,快速关注我们)


编译:雁惊寒  英文:ShutIt 

www.iteye.com/news/32482

如有好文章投稿,请点击 → 这里了解详情


译者注:本文通过实例简单介绍了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)


运行这个文件:


python example.py


输出:


python example.py  

echo "Hello World"  

echo "Hello World"  

Hello World  

Ians-MacBook-Air.local:ORIGIN_ENV:RhuebR2T#


“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()


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


hostname  

hostname  

example.com  

example.com:cgoIsdVv:heDa77HB#


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


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 ()


它会让你输入密码:


Input Secret:  

hostname  

hostname  

example.com  

example.com:cgoIsdVv:heDa77HB#


同样的,“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()


将输出这样的结果:


$ 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#


实例:监控多台服务器


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


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()


在这里,我们用了“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()


注意“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 MovedTITLE>HEAD><BODY>  

<H1>302 MovedH1>  

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.


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


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


暂停点


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


[...]  

session.pause_point('This is a pause point')  

[...]


当脚本运行到暂停点时,同时按下“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)


程序输出:


$ 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#


更复杂的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')


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


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


更多信息


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


  • ShutIt (https://ianmiell.github.io/shutit/)

  • GitHub (https://github.com/ianmiell/shutit/blob/master/README.md)


看完本文有收获?请转发分享给更多人

关注「Python开发者」,提升Python技能


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/V7cuUCG7ud
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/2400
 
557 次点击