python模块之 - subprocess执行unix/linux命令
2017-08-19 17:48
239 查看
subprocess模块提供了一种一致的方法来创建和处理附加进程,与标准库中的其它模块相比,提供了一个更高级的接口,subprocess模块用来生成子进程,并可以通过管道连接它们的
输入/输出/错误,以及获得它们的返回值.它用来代替多个旧模块和函数:
os.system
os.spawn*
os.popen*
popen2.*
commands.*
1.subprocess.call( commands ) 方法 :
subprocess的call方法可以用于执行一个外部命令,但该方法不能返回执行的结果,只能返回执行的状态码:成功(0)或错误(非0)
call()方法中的commands可以是一个列表,也可以是一个字符串,作为字符串时需要用原生的shell=True来执行:
示例:
2.subprocess.check_call() 方法:
我们说过call执行返回一个状态码,我们可以通过check_call()函数来检测命令的执行结果,如果不成功将返回 subprocess.CalledProcessError 异常
#如果命令执行正确则返回结果,和subprocess.call效果一样.
示例:
subprocess.call 和subprocess.check_call的区别:
subprocess.call:执行命令,返回结果
check_all :执行命令,如果执行状态码是0,则返回0,否则抛出异常.
subprocess.call如果命令执行错误不会抛出异常(经测试在linux系统上执行错误命令也会有异常错误,在pycharm上面则不抛出异常),而subprocess.check_call如果命令执行错误则抛出异常,如果命令执行正确则两者效果一样.
3.subprocess.Popen()方法:
函数call(), check_call() 和 check_output() 都是Popen类的包装器。直接使用Popen会对如何运行命令以及如何处理其输入输出有更多控制。如通过为stdin, stdout和stderr传递不同的参数。
1.与进程的单向通信
通过Popen()方法调用命令后执行的结果,可以设置stdout值为PIPE,再调用communicate()获取结果 返回结果为tuple. 在python3中结果为byte类型,要得到str类型需要decode转换一下输出结果(读)
2 与进程的双向通信:
Popen其它方法:
脚本实例:
PHP代码备份及目录过滤
输入/输出/错误,以及获得它们的返回值.它用来代替多个旧模块和函数:
os.system
os.spawn*
os.popen*
popen2.*
commands.*
1.subprocess.call( commands ) 方法 :
subprocess的call方法可以用于执行一个外部命令,但该方法不能返回执行的结果,只能返回执行的状态码:成功(0)或错误(非0)
call()方法中的commands可以是一个列表,也可以是一个字符串,作为字符串时需要用原生的shell=True来执行:
示例:
>>> import subprocess >>> subprocess.call(["ls","-lh"]) total 8.0K -rw-r--r--. 1 root root 941 Oct 22 2013 socket_2.py -rw-r--r--. 1 root root 401 Oct 22 2013 socket_client.py 0 >>> subprocess.call("ls -lh",shell=True) total 8.0K -rw-r--r--. 1 root root 941 Oct 22 2013 socket_2.py -rw-r--r--. 1 root root 401 Oct 22 2013 socket_client.py 0 >>> 如上实例所示,虽然我们能看到执行的结果和返回的一个状态码0,但保存为变量后实际获取的值只是状态码 >>> cmd_result = subprocess.call("ls -lh",shell=True) total 8.0K -rw-r--r--. 1 root root 941 Oct 22 2013 socket_2.py -rw-r--r--. 1 root root 401 Oct 22 2013 socket_client.py >>> print(cmd_result) 0 >>>
2.subprocess.check_call() 方法:
我们说过call执行返回一个状态码,我们可以通过check_call()函数来检测命令的执行结果,如果不成功将返回 subprocess.CalledProcessError 异常
#如果命令执行正确则返回结果,和subprocess.call效果一样.
示例:
>>> try: ... subprocess.check_call("ls -lh",shell=True) ... except subprocess.CalledProcessError as err: ... print("Commands error") ... total 8.0K -rw-r--r--. 1 root root 941 Oct 22 2013 socket_2.py -rw-r--r--. 1 root root 401 Oct 22 2013 socket_client.py 0 >>> #如果命令执行错误,则抛出异常. >>> try: ... subprocess.check_call("ls -jj",shell=True) ... except subprocess.CalledProcessError as err: ... print("Commands error") ... ls: invalid option -- 'j' Try `ls --help' for more information. Commands error >>>
subprocess.call 和subprocess.check_call的区别:
subprocess.call:执行命令,返回结果
check_all :执行命令,如果执行状态码是0,则返回0,否则抛出异常.
subprocess.call如果命令执行错误不会抛出异常(经测试在linux系统上执行错误命令也会有异常错误,在pycharm上面则不抛出异常),而subprocess.check_call如果命令执行错误则抛出异常,如果命令执行正确则两者效果一样.
3.subprocess.Popen()方法:
函数call(), check_call() 和 check_output() 都是Popen类的包装器。直接使用Popen会对如何运行命令以及如何处理其输入输出有更多控制。如通过为stdin, stdout和stderr传递不同的参数。
1.与进程的单向通信
通过Popen()方法调用命令后执行的结果,可以设置stdout值为PIPE,再调用communicate()获取结果 返回结果为tuple. 在python3中结果为byte类型,要得到str类型需要decode转换一下输出结果(读)
# 直接执行命令输出到屏幕 >>> subprocess.Popen("ls -lh",shell=True) <subprocess.Popen object at 0x7f8ad576c450> >>> total 8.0K -rw-r--r--. 1 root root 941 Oct 22 2013 socket_2.py -rw-r--r--. 1 root root 401 Oct 22 2013 socket_client.py >>> # 不输出到屏幕,输出到变量 #读取字符串 >>> cmd_result=subprocess.Popen(["echo","welcome to china"],stdout=subprocess.PIPE) >>> print(cmd_result) <subprocess.Popen object at 0x7f8ad576c9d0> >>> stdout_var=cmd_result.communicate() >>> stdout_var ('welcome to china\n', None) >>> print((stdout_var[0]).decode('utf-8')) welcome to china >>> #读取命令输出结果 >>> cmd_result=subprocess.Popen(["ls","-lh"],stdout=subprocess.PIPE) >>> print(cmd_result) <subprocess.Popen object at 0x7f8ad576c990> >>> stdout_var=cmd_result.communicate() >>> print((stdout_var[0]).decode("utf-8")) total 8.0K -rw-r--r--. 1 root root 941 Oct 22 2013 socket_2.py -rw-r--r--. 1 root root 401 Oct 22 2013 socket_client.py >>> #将结果输出到文件 >>> file_handle = open("/tmp/t.logs","w+") >>> subprocess.Popen("ls -lh",shell=True,stdout=file_handle) <subprocess.Popen object at 0x7f8ad576c990> >>> #在指定路径创建目录 >>> import subprocess >>> obj = subprocess.Popen("mkdir t3",shell=True,cwd="/tmp",) >>> obj = subprocess.Popen("mkdir t4",shell=True,cwd="/tmp") >>>
2 与进程的双向通信:
>>> cmd_result=subprocess.Popen("cat",shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE) >>> msg="Hello World".encode("utf-8") # 写入到输入管道 >>> cmd_result.stdin.write(msg) >>> stdout_var=cmd_result.communicate() >>> stdout_var ('Hello World', None) >>> (stdout_var[0]).decode("utf-8") u'Hello World' >>> (stdout_var[0]).decode() u'Hello World' >>> >>> stdout_var[0] 'Hello World' >>> #打开一个python终端,执行python print命令. >>> cmd_result=subprocess.Popen(["python"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> cmd_result.stdin.write('print("Good luck!")'.encode("utf-8")) >>> stdin_var,err_var=cmd_result.communicate() >>> print(err_var) >>> print(stdin_var) Good luck! >>> stdin_var 'Good luck!\n' >>>
Popen其它方法:
poll() | 检查是否结束,设置返回值 |
wait() | 等待结束,设置返回值 |
communicate() | 参数是标准输入,返回标准输出和标准出错 |
send_signal() | 发送信号 (主要在unix下有用) |
terminate() | 终止进程,unix对应的SIGTERM信号,windows下调用api函数TerminateProcess() |
kill() | 杀死进程(unix对应SIGKILL信号),windows下同上 |
stdin stdout stderr | 参数中指定PIPE时,有用 |
pid | 进程id |
returncode | 进程返回值 |
#!/usr/bin/env python #coding:utf-8 import os import time import subprocess packge_dir = "/root/.jenkins/workspace/pre-php-p/" remote_ip = "59.110.164.99" remote_port = "'-e ssh -p 6168'" backup_dir= '/data/backup/' + time.strftime('%Y%m%d') source_dir="shop-H5" source_URL="/data/web/xd" def backup_php(): tagz = backup_dir + os.sep + source_dir + "_" + time.strftime('%Y%m%d%H') + '.tgz' print "tagz=",tagz backup_tgz = "tar -zcvf %s %s" %(tagz,source_dir) if not os.path.exists(backup_dir): os.mkdir(backup_dir) print("Sucessfully created directory",backup_dir) print("开始备份代码中...") os.chdir(source_URL) #os.system(backup_tgz) #subprocess.call(backup_tgz,shell=True) if subprocess.call(backup_tgz,shell=True) == 0: print "Successful backup to ", tagz else: print "Backup FAILED!!" time.sleep(3) def rsync_php(): print("开始代码同步中...") remote_ssh = remote_ip + ":" + packge_dir time.sleep(3) rsyn="/usr/bin/sudo rsync -avH --progress --exclude=.git %s %s %s" %(remote_port,remote_ssh,source_dir) #print rsyn if subprocess.call(rsyn,shell=True) == 0: print("同步代码成功...") else: print("同步代码失败,check...") #os.chown(source_dir,504,504) mattr="chown -R phpci:phpci %s" %(source_dir) subprocess.call(mattr,shell=True) if __name__ == "__main__": backup_php() rsync_php()
PHP代码备份及目录过滤
相关文章推荐
- pig脚本不需要后缀名(python tempfile模块生成pig脚本临时文件,执行)
- 利用python fabric模块写的批量操作远程主机脚本(命令执行,上传、下载文件)
- [Python] 利用commands模块执行Linux shell命令
- pythontips(1):打印模块的属性并执行
- [Python2.x] 利用commands模块执行Linux shell命令
- Python进阶(一)——安装Python、程序执行、Python模块和IDLE调试
- Python模块调用与执行
- python 知识点:反射 之 getattr()实现以字符串形式导入模块和执行函数
- Python基础篇【第6篇】: Python模块subprocess
- Python进阶——安装Python、程序执行、Python模块和IDLE调试
- Python paramiko模块 实现 ssh远程执行命令 上传下载文件 堡垒机模式下的远程命令执行
- python模块:调用系统命令模块subprocess等
- python3 timeit:计算小段代码的执行时间的模块
- python模块:调用系统命令模块subprocess等
- python模块 - subprocess
- python 一个模块要执行其它模块主要有三种方法
- python通过getopt模块如何获取执行的命令参数详解
- python判断模块是直接执行还是加载模块
- python基础-tcp粘包、解决方案、subprocess执行shell命令
- python脚本初探---新手如何直接编写一个hello world模块即可执行的.py文件