python模块之 - subprocess执行unix/linux命令
subprocess模块提供了一种一致的方法来创建和处理附加进程,与标准库中的其它模块相比,提供了一个更高级的接口,subprocess模块用来生成子进程,并可以通过管道连接它们的
输入/输出/错误,以及获得它们的返回值.它用来代替多个旧模块和函数:
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- import os
import sys
import subprocess
import time
import signal TOMCAT_HOME="/usr/local/tomcat-fraud/"
TOMCAT_PORT=
remote_ip="123.56.219.121"
remote_port="'-e ssh -p 6168'" try:
backup_dir='/data/backup/' + sys.argv[] + os.sep + time.strftime('%Y%m%d')
except IndexError:
print("example : python fraud-dev.sh < projectname >") if len(sys.argv) < :
print("you must use like this : python fraud-dev.sh <projectname>")
sys.exit()
if not os.path.isdir(backup_dir):
os.makedirs(backup_dir)
print("Sucessfully created directory",backup_dir)
else:
print("directory alreaty exist") #备份的模块(将项目的war包从jenkins目录取下来放到本地目录.)
def backup():
print("download fraud.war...")
#Jenkins服务器存放war包的目录
packge_dir="/root/.jenkins/workspace/fraud-dev/fraud-web/target/"
remote_ssh = remote_ip + ":" + packge_dir + sys.argv[] + ".war"
print(remote_ssh)
#remote_ssh = remote_ip + ":" + packge_dir
rsyn="/usr/bin/sudo rsync -avH --progress %s %s %s" %(remote_port,remote_ssh,backup_dir) if subprocess.call(rsyn,shell=True) == :
print("download fraud.war sucess...")
else:
print("同步代码失败,check...")
#代码更新函数:
def rsync_java():
target_dir=TOMCAT_HOME + "webapps/"
#os.chdir(target_dir)
subprocess.Popen("rm -rf *", shell=True, cwd=target_dir)
time.sleep()
print("开始更新代码中...")
rsync_ssh="/usr/bin/sudo rsync -avH --progress %s %s" %(backup_dir,target_dir)
if subprocess.call(rsync_ssh,shell=True) == :
print("代码更新完成...")
else:
print("代码更新失败...") #启停Java服务.
def kill_pid(pid):
try:
a = os.kill(pid, signal.SIGKILL)
print("已杀死pid为%s的进程,返回值是:%s" % (pid, a))
except OSError:
print("没有这个进程号") def start_java():
java_service= TOMCAT_HOME + "bin/startup.sh"
os.system(java_service)
time.sleep()
print("tomcat 启动完成...") if __name__ == "__main__":
backup()
li = []
#cmd="/usr/sbin/lsof -i:80 |egrep -v PID | awk {'print $2'} |sort -nr|uniq"
cmd="/usr/sbin/lsof -i:%s | grep java |awk {'print $2'}" %(TOMCAT_PORT)
pid = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# print(pid.stdout.readlines())
for m in pid.stdout.readlines():
li.append(int(m))
for i in li:
kill_pid(i)
time.sleep()
print("开始上传代码中...")
rsync_java()
start_java()
java备份和上传代码
#!/usr/bin/env python
#coding:utf- import os
import time
import subprocess packge_dir = "/root/.jenkins/workspace/shop-H5/"
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" def backup_php(): tgz = backup_dir + os.sep + "shop-H5_" + time.strftime('%Y%m%d%H') + '.tgz'
backup_tgz = "tar -zcvf %s %s" % (tgz,source_dir) #print(time.strftime('%Y-%m-%d-%H:%M'))
#print(backup_dir)
if not os.path.exists(backup_dir):
os.mkdir(backup_dir)
print("Sucessfully created directory",backup_dir) print("开始备份代码中...")
os.chdir('/opt')
if subprocess.call(backup_tgz,shell=True) == :
print("Successful backup to ", tgz)
else:
print("Backup FAILED!!") time.sleep() def rsync_php(): print("开始代码同步中...")
remote_ssh = remote_ip + ":" + packge_dir
rsyn = "/usr/bin/sudo rsync -avH --progress %s %s %s" %(remote_port,remote_ssh,source_dir) if subprocess.call(rsyn,shell=True) == :
print("同步代码成功...")
else:
print("同步代码失败,check...")
#递归改变目录的权限
#os.chown(source_dir,,)
mattr="chown -R phpci:phpci %s" %(source_dir)
#subprocess.call(mattr,shell=True)
subprocess.call(mattr,shell=True) if __name__ == "__main__":
backup_php()
rsync_php() PHP代码备份及上传
PHP代码备份及上传
#!/usr/bin/env python
#coding:utf- 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) == :
print "Successful backup to ", tagz
else:
print "Backup FAILED!!" time.sleep()
def rsync_php(): print("开始代码同步中...") remote_ssh = remote_ip + ":" + packge_dir time.sleep() 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) == :
print("同步代码成功...") else:
print("同步代码失败,check...") #os.chown(source_dir,,)
mattr="chown -R phpci:phpci %s" %(source_dir)
subprocess.call(mattr,shell=True) if __name__ == "__main__":
backup_php()
rsync_php()
PHP代码备份及目录过滤
python模块之 - subprocess执行unix/linux命令的更多相关文章
- 后台执行UNIX/Linux命令和脚本的五种方法
hiveserver 后台启动 nohup "${HIVE_HOME}"/bin/hive --service hiveserver2 & 1. 使用&符号在后台执 ...
- 20个 Unix/Linux 命令技巧
让我们用这些Unix/Linux命令技巧开启新的一年,提高在终端下的生产力.我已经找了很久了,现在就与你们分享. 删除一个大文件 我在生产服务器上有一个很大的200GB的日志文件需要删除.我的rm和l ...
- 开发错误日志之Unix/Linux命令未执行或无结果等且程序无错误
在Unix/Linux环境中开发时,特别要注意权限问题,否则经常找不到错误的原因,其实就是因为权限所致.
- [转载]Python模块学习 ---- subprocess 创建子进程
[转自]http://blog.sciencenet.cn/blog-600900-499638.html 最近,我们老大要我写一个守护者程序,对服务器进程进行守护.如果服务器不幸挂掉了,守护者能即时 ...
- 14.python模块之subprocess
我们几乎可以在任何操作系统上通过命令行指令与操作系统进行交互,比如Linux平台下的shell.那么我们如何通过Python来完成这些命令行指令的执行呢?另外,我们应该知道的是命令行指令的执行通常有两 ...
- 批量执行(Linux命令,上传/下载文件)
前言: 每个公司的网络环境大都划分 办公网络.线上网络,之所以划分的主要原因是为了保证线上操作安全: 对于外部用户而言也只能访问线上网络的特定开放端口,那么是什么控制了用户访问线上网络的呢? 防火墙过 ...
- Unix/Linux命令:SED
在Unix/Linux系统中,sed命令采用逐行处理的方式对文件进行查找.删除.替换.添加.插入等操作. 语法:sed [OPTION]... {script-only-if-no-other-scr ...
- 万能脚本助Web执行底层Linux命令
需求分析: 这里先要说明的是,这一篇不是QT系列的文章,而是关于Web的,之所以要写这篇,是因为以前做Web相关开发的时候,经常涉及到与linux底层命令打交道,比如说创建一个目录,删除一个目录,或者 ...
- 汉高澳大利亚sinox为什么不能下载源代码,因为sinox执行unix/linux/windows规划
中国用户下载真正的澳大利亚sinox说完后sinox没有下载源代码. 这意味着,类似linux如下载linux 开源安装. 要知道.sinox并非linux. 首先,sinox是商业操作系统,就像 w ...
随机推荐
- linux centOS6 nexus 开启自动启动
sudo ln -s /opt/nexus-2.6.4/nexus-2.6.4-02/bin/nexus /etc/init.d/nexus 使用 service nexus status/star ...
- 解决chrome extension无法下载的问题
由于GFW把谷歌应用商店给屏蔽了,下载chrome扩展变得很困难. 我使用的是版本30.0.1599.101 m. 那么你需要做的第一个处理是,修改host文件,保证chrome应用商店可以登录.如下 ...
- 5. 支持向量机(SVM)软间隔
1. 感知机原理(Perceptron) 2. 感知机(Perceptron)基本形式和对偶形式实现 3. 支持向量机(SVM)拉格朗日对偶性(KKT) 4. 支持向量机(SVM)原理 5. 支持向量 ...
- 11月Android笔记
不知不觉又过了两个月了,过的够呛.新收获:百度云,视频直播,sqlite加密,lucene,SlidingPaneLayout. 我发现只要你有心,你期望的事情会接踵而来(不包括爱情= =) 上个游戏 ...
- [转]SpringMVC<from:form>表单标签和<input>表单标签简介
原文地址:https://blog.csdn.net/hp_yangpeng/article/details/51906654 在使用SpringMVC的时候我们可以使用Spring封装的一系列表单标 ...
- [Linux]基本I/O重定向
在我们设置定时任务的时候经常会使用标准输出和标准错误输出.这个在Linux是一个非常重要的概念,而且这个很有用.程序应该有数据库的来源端.数据的目的端,以及报告问题的地方,它们被称为标准输入.标准输出 ...
- Java编程的逻辑 (41) - 剖析HashSet
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...
- 编译安装LAMP之安装Apache+php与管理(十五)
[教程主题]:编译安装LAMP之安装Apache+php与管理 [课程录制]: 创E [主要内容] [1]编译安装Apache+PHP 1.安装程序依赖库和开发环境 为了省事把所需要的库文件全都安装上 ...
- hbase源码系列(十四)Compact和Split
先上一张图讲一下Compaction和Split的关系,这样会比较直观一些. Compaction把多个MemStore flush出来的StoreFile合并成一个文件,而Split则是把过大的文件 ...
- 1px的border
css中是这样写的: div{ border-bottom: 1px solid #dfe5e4; } 但在手机上,像素比不为 1 ,由于 webview 的灰度渲染, border 一般会显示为 2 ...