zoukankan      html  css  js  c++  java
  • ShutIt:一个基于 Python 的 shell 自动化框架

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

    更复杂的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 Moved</TITLE></HEAD><BODY>  
    <H1>302 Moved</H1>  
    The document has moved  
    <A HREF="http://www.google.co.uk/?gfe_rd=cr&amp;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)

  • 相关阅读:
    C语言 sprintf 函数 C语言零基础入门教程
    C语言 printf 函数 C语言零基础入门教程
    C语言 文件读写 fgets 函数 C语言零基础入门教程
    C语言 文件读写 fputs 函数 C语言零基础入门教程
    C语言 fprintf 函数 C语言零基础入门教程
    C语言 文件读写 fgetc 函数 C语言零基础入门教程
    C语言 文件读写 fputc 函数 C语言零基础入门教程
    C语言 strlen 函数 C语言零基础入门教程
    Brad Abrams关于Naming Conventions的演讲中涉及到的生词集解
    适配器模式
  • 原文地址:https://www.cnblogs.com/royfans/p/7196887.html
Copyright © 2011-2022 走看看