Python执行外部命令

subprocess模块简介

这个模块用来创建和管理子进程。它提供了高层次的接口,用来替换os,system(),os.spawn*(),os.popen*(),os.popen2.*()和commands.*等模块和函数。

subprocess提供了一个名为Popen的类启动和设置子进程的参数,由于这个类比较复杂,subprocess还提供了若干遍历的函数,这些函数都是对Popen类的封装。

subprocess模块的便利函数

call函数的定义:

subprocess.cal(args, *,stdin=None, stdout=None, stderr=None, shell=False )
示例代码
In [1]: import subprocess                                                                               
In [2]: subprocess.call(['ls','-l'])                 
总用量 8
-rw-------. 1 root root 1595 2月   7 00:33 anaconda-ks.cfg
-rw-r--r--. 1 root root 1643 2月   7 00:34 initial-setup-ks.cfg
drwxr-xr-x. 2 root root    6 2月   7 00:37 公共
drwxr-xr-x. 2 root root    6 2月   7 00:37 模板
drwxr-xr-x. 2 root root    6 2月   7 00:37 视频
drwxr-xr-x. 2 root root    6 2月   7 00:37 图片
drwxr-xr-x. 2 root root    6 2月   7 00:37 文档
drwxr-xr-x. 2 root root    6 2月   7 00:37 下载
drwxr-xr-x. 2 root root    6 2月   7 00:37 音乐
drwxr-xr-x. 2 root root    6 2月   7 00:37 桌面
Out[2]: 0

In [3]: subprocess.call('exit 1',shell=True)          Out[3]: 1

check_call

check_call函数的作用与call函数类似,区别在于异常情况下返回的形式不同。

对于call函数,工程师通过捕获call命令的返回值判断命令是否执行成功,如果成功则返回0,否则的话返回非0,对于check_call函数,如果执行成功,返回0,如果执行失败,抛出subprocess.CalledProcess错误异常

代码示例
In [8]: subprocess.check_call(['ls','-l'])                                                                                   
总用量 8
-rw-------. 1 root root 1595 2月   7 00:33 anaconda-ks.cfg
-rw-r--r--. 1 root root 1643 2月   7 00:34 initial-setup-ks.cfg
drwxr-xr-x. 2 root root    6 2月   7 00:37 公共
drwxr-xr-x. 2 root root    6 2月   7 00:37 模板
drwxr-xr-x. 2 root root    6 2月   7 00:37 视频
drwxr-xr-x. 2 root root    6 2月   7 00:37 图片
drwxr-xr-x. 2 root root    6 2月   7 00:37 文档
drwxr-xr-x. 2 root root    6 2月   7 00:37 下载
drwxr-xr-x. 2 root root    6 2月   7 00:37 音乐
drwxr-xr-x. 2 root root    6 2月   7 00:37 桌面
Out[8]: 0

check_output

代码示例
In [13]: output = subprocess.check_output(['df','-h'])                                                                       
In [14]: print(output.decode())                                                                                              
文件系统                 容量  已用  可用 已用% 挂载点
devtmpfs                 1.9G     0  1.9G    0% /dev
tmpfs                    1.9G     0  1.9G    0% /dev/shm
tmpfs                    1.9G   21M  1.9G    2% /run
tmpfs                    1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/mapper/centos-root   17G  4.8G   13G   29% /
/dev/sda1               1014M  185M  830M   19% /boot
tmpfs                    378M  4.0K  378M    1% /run/user/42
tmpfs                    378M   64K  378M    1% /run/user/0
In [16]: lines = output.decode().split('\n')                                                                                 
In [17]: lines                                                                                                               
Out[17]: 
['文件系统                 容量  已用  可用 已用% 挂载点',
 'devtmpfs                 1.9G     0  1.9G    0% /dev',
 'tmpfs                    1.9G     0  1.9G    0% /dev/shm',
 'tmpfs                    1.9G   21M  1.9G    2% /run',
 'tmpfs                    1.9G     0  1.9G    0% /sys/fs/cgroup',
 '/dev/mapper/centos-root   17G  4.8G   13G   29% /',
 '/dev/sda1               1014M  185M  830M   19% /boot',
 'tmpfs                    378M  4.0K  378M    1% /run/user/42',
 'tmpfs                    378M   64K  378M    1% /run/user/0',
 '']
In [19]: for line in lines[1:-1]: 
    ...:     if line: 
    ...:         print(line.split()[-2]) 
    ...:                                                                                                                     
0%
0%
2%
0%
29%
19%
1%
1%
In [22]: try: 
    ...:     output = subprocess.check_output(['df','-h']).decode() 
    ...: except subprocess.CalledProcessError as e: 
    ...:     output = e.output 
    ...:     code = e.returncode 

Popen类

代码示例

execute_demo.py文件

# coding=utf-8
import subprocess


def execute_cmd(cmd):
    p = subprocess.Popen(cmd, shell=True,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()

    if p.returncode != 0:
        return p.returncode, stderr
    return p.returncode, stdout


execute_cmd('ls')

部署安装mongodb

需要用到mongodb-linux-x86_64-rhel70-4.2.3.tgz文件

编写脚本

# coding=utf-8
import subprocess
import os
import shutil
import tarfile


def execute_cmd(cmd):
    '''执行shell命令'''
    p = subprocess.Popen(cmd, shell=True,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()
    if p.returncode != 0:
        return p.returncode, stderr
    return p.returncode, stdout


def unpackage_mongo(package, package_dir):
    unpackage_dir = os.path.splitext(package)[0]
    if os.path.exists(unpackage_dir):
        shutil.rmtree(unpackage_dir)
    if os.path.exists(package_dir):
        shutil.rmtree(package_dir)
    # 解压
    try:
        t = tarfile.open(package, 'r:gz')
        t.extractall('.')

        print('tar is ok.')
    except Exception as e:
        print(e)
    # 重命名
    shutil.move(unpackage_dir, 'mongo')


def create_datadir(data_dir):
    if os.path.exists(data_dir):
        shutil.rmtree(data_dir)
    os.mkdir(data_dir)


def format_mongod_commamd(package_dir, data_dir, logfile):
    mongod = os.path.join(package_dir, 'bin', 'mongod')
    mongod_format = """{0} --fork --dbpath {1} --logpath {2}"""
    return mongod_format.format(mongod, data_dir, logfile)


def start_mongod(cmd):
    returncode, out = execute_cmd(cmd)
    if returncode != 0:
        raise SystemExit('execute {0} error:{1}'.format(cmd, out))
    else:
        print('execute {0} successfuly.'.format(cmd))


def main():
    package = 'mongodb-linux-x86_64-rhel70-4.2.3.tgz'
    cur_dir = os.path.abspath('.')
    package_dir = os.path.join(cur_dir, 'mongo')
    data_dir = os.path.join(cur_dir, 'mongodata')
    logfile = os.path.join(data_dir, 'mongod.log')

    if not os.path.exists(package):
        raise SystemExit('{0} not found.'.format(package))

    unpackage_mongo(package, package_dir)
    create_datadir(data_dir)
    start_mongod(format_mongod_commamd(package_dir, data_dir, logfile))


main()

启动

[root@localhost script]# python auto_install_mongodb.py 
tar is ok.
execute /opt/script/mongo/bin/mongod --fork --dbpath /opt/script/mongodata --logpath /opt/script/mongodata/mongod.log successfuly.

查看端口

[root@localhost script]# netstat -anpt | grep mongod
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      76930/mongod   

进入mongo

[root@localhost script]# cd mongo/bin/
[root@localhost bin]# ./mongo
...
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

> 
Python自动化运维--基于shell命令进行封装
编写自动化脚本-->用Python语法封装shell命令的执行过程
python执行shell命令--python外部命令
python函数执行shell命令
os.system(cmd)
subprocess模块
subprocess.call(['ls','-l'])
subprocess.call('ll',shell=True)
运行成功:返回0
运行失败:返回非0
subprocess.check_call(['ls','-l'])
subprocess.checl_all('ll',shell=True)
运行成功:返回0
运行失败:返回CalledProcessError
subprocess.check_output(['cat','apache.log',stderr=subprocess.STDOUT])
运行成功:返回命令的输出结果
运行失败:自定义错误输出stderr
subprocess模块的Popen类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值