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类