ShutIt:一个基于Python的shell自动化框架
创始人
2025-02-13 22:30:27
0次

[[194837]]

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

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

Hello World

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

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

运行这个文件:

  1. python example.py 

输出:

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

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

登录服务器

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

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

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

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

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

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

它会让你输入密码:

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

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

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

登录到多台服务器

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

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

将输出这样的结果:

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

实例:监控多台服务器

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

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

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

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

更复杂的IO – Expecting

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

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

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

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

  1. $ python example.py 
  2.  
  3. telnet 
  4.  
  5. telnet> open google.com 80 
  6.  
  7. Trying 216.58.214.14... 
  8.  
  9. Connected to google.com. 
  10.  
  11. Escape character is '^]'. 
  12.  
  13. GET / 
  14.  
  15. HTTP/1.0 302 Found 
  16.  
  17. Cache-Control: private 
  18.  
  19. Content-Type: text/html; charset=UTF-8 
  20.  
  21. Referrer-Policy: no-referrer 
  22.  
  23. Location: http://www.google.co.uk/?gfe_rd=cr&ei=huczWcj3GfTW8gfq0paQDA 
  24.  
  25. Content-Length: 261 
  26.  
  27. Date: Sun, 04 Jun 2017 10:57:10 GMT 
  28.  
  29.  
  30.  
  31. 302 Moved 
  32.  
  33. 302 Moved

     
  34.  
  35. The document has moved 
  36.  
  37.  
  38.  
  39. here 
  40.  
  41. . 
  42.  
  43.  
  44.  
  45. Connection closed by foreign host.  

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

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

暂停点

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

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

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

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

程序输出:

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

更复杂的IO – Backgrounding

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

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

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

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
只需三步,让你掌握阿尔法路由器... 请参照以下阿尔法路由器设置方法,通过浏览器进入及设置宽带路由器。经过这三个步骤的设置,基本上能够熟悉...
如何更省钱? 近期特价热门硒鼓... 如今激光打印设备已经成为商务或企业的绝对主力办公设备,但采购者往往忽视了激光打印设备所用的耗材,相对...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...