星光

用Python调用Shell脚本

id=48373553

今天和DIYGod聊天,他的网站有时候会宕机,重启下就行了,正好之前看到 Find 的文章有些感想

PYTHON监视网站是否宕机GET和POST方式

想到一个思路,用python判断场景后执行对应的shell脚本文件,来实现自动化地宕机重启

虽然现在没有在VPS上搭建博客,以后要用可能也不是这个场景,但是还是觉得去研究下非常有意义,做如下记录

主要有两种方法: os.system(cmd)或os.popen(cmd)

首先你需要导入os模块

然后可以在括号中直接敲 Linux(OS X应该也可以)指令

两者有一定区别,看的文章中说“前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容”

然而我在 Python3下测试直观前者更方便(写到后面我发现后面的意义也很大),后者返回的是一个 file-like 的对象,你可以利用相对于的文件方法进行优化处理

chrom下右键新标签页打开查看大图

宕机监测和对应的判断分支语句我给省略了,主要看下这个场景(其实是我懒+没写过233)

首页shell脚本写好后,别忘了chmod,加上执行权限

代码版:

第一个是相对于指令执行后,我们人看到的内容,第二个是返回值

该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码,即脚本中“exit 1”的代码执行后,os.system函数返回值的高位数则是1,如果低位数是0的情况下,则函数的返回值是0×100,换算为10进制得到256。

这个学过单片机和汇编的同学应该很好理解,其实学过数电也行(上学期这三门我同时学的)

需要注意的是b作为变量只能接受第二个值,第一个值直接打印到了终端上,这个对程序处理来说显然是无法进行储存和二次使用的

所以如果比较在shell脚本中输出的内容,并且要进行二次处理的话,使用方法二

而方法一的返回值也意义很大,我之前考虑过一个场景,如果在自动调用后,判断是否调用成功,不成功再次反复调用shell脚本,或者执行对应的修复分支

这个时候 我储存b变量的作用就体现了,我们设置可以设置多个脚本文件及其对应的返回值来进行对应的分支场景判断,增强程序的健壮性和功能性

主要注意的是cmd需要以字符串形式放在括号中,如果短的可以自己直接在python语句中写,但是我个人还是更倾向写成shell脚本形式

然后用形如  “./1.sh”  或者”绝对路径/1.sh”的方式运行,注意一定要指明路径,不然是无法运行的

这不像cd到对应的路径下,可以用python+文件名直接执行python脚本一样

写成脚本形式的好处:

1、便于分开编辑

2、python我个人很多时候是在命令行直接敲的,这个时候用文件编辑器改shell文件明显比在命令行里面一行行敲代码来得方便

以上,希望这篇文章也能给你提供一种Linux下的自动化思路,还有些其他技能参考后面的链接,这里就不一一赘述了

参考资料:

os模块教程

python调用shell脚本的两种方法

python学习——python中执行shell命令

 

 

如无特殊声明,欢迎转载,但是请注明来自星之所在《用Python调用Shell脚本》

评论

  1. Starlight #1

    顺便一提,配合cron使用效果更佳~你懂的

    回复
    2015-03-22
  2. Puteulanus #2

    _(:з」∠)_可以把
    if ! curl -s -I -m 30 “http://jimmy66.com” | head -1 | grep -q ‘[23]0[0-9]’
    then
    service nginx restart
    这种直接写cron里,这个比Python脚本简单感觉。。

    回复
    2015-03-22
    • Starlight

      终结。。虽然curl,nginx,grep 都认识,但是还是看不太懂这指令233

      回复
      2015-03-22
  3. Puteulanus #3

    其实原理挺简单的。
    curl读网页,-s参数表示静默模式,不显示错误和进度;-I表示只读取server的回应,不含内容;-m表示设定超时时间,免得进程卡上了。
    读出来是这个样子的:
    HTTP/1.1 200 OK
    Date: Mon, 23 Mar 2015 16:10:46 GMT
    Server: Apache/2
    X-Powered-By: PHP/5.3.29
    Vary: Accept-Encoding,Cookie,User-Agent
    Cache-Control: max-age=3, must-revalidate
    WP-Super-Cache: Served supercache file from PHP
    Content-Type: text/html; charset=UTF-8
    然后结果传递给head,head -1表示只要第一行。
    处理完变成酱紫:
    HTTP/1.1 200 OK
    再然后结果传给grep去匹配,-q表示安静模式,不打印任何标准输出。如果有匹配的内容则立即返回状态值0。grep等于是把“是否存在状态码20X(如200,正确返回)/30X(如301和302跳转)”转换成了布尔型作为if的条件。
    最后就是经if判断不存在20X/30X的状态码(比如返回的是403、504之类的,表示网站挂了)时,执行的命令,这个就可以自己随意写了,比如把nginx、php-fpm还有缓存服务(如果有的话)挨个restart下,或者比较简单的直接reboot也行。
    不过reboot有个坑在于如果不是服务问题,比如你手滑自己把主页给删了报404,这种重启不能解决问题的,它会一直重启重启重启。。一般还是重启相关服务比较好我感觉。

    回复
    2015-03-24
    • Starlight

      给菊苣跪了。。。容我慢慢学习

      回复
      2015-03-24
    • Starlight

      reboot那段看笑了,不过设置了cron的话应该还是有时间间隔去修改的,确实应该针对服务去重启,能小点,能局部最好了~

      回复
      2015-03-24
  4. Starlight #4

    发现了这个项目~由于laike9m前辈的star注意到的 https://github.com/fengsp/plan

    回复
    2015-04-18
  5. Wzl #5

    感谢分享 找了半天print(os.popen())的错误

    回复
    2017-10-29