python之subprocess模块rsync拉取文件

这里以 tornado 框架为例,由于文件大小不确定,也许会非常大,所以使用异步回调的方式。上代码:

import re
import tornado
import sys
import subprocess
reload(sys)
sys.setdefaultencoding('utf8')

CURRENT_DUMP = {}
class FileHandler():
	executor = ThreadPoolExecutor(20)

	@tornado.web.asynchronous
	@tornado.gen.engine
	def get(self, param):            #接收get请求
		callback = self.get_argument("callback", "callback")

		# 拉取文件
		if (param == 'filepull'):
			file_id = self.get_argument("file_id ", "")
            # 校验用户操作文件的权限
            # ... 
            # 把此次同步记录到log里
            log_id = self.addLog(user_id, file_id, 'pull', '未开始', '')
			if log_id == 0:
				self.write('%s({"status":"创建日志失败"})' % callback)
			else:	
    			tornado.ioloop.IOLoop.instance().add_callback(self.filepull_impl, log_id)
			self.write('%s({"status":"已加入到队列,请稍后查看日志","log_id":%d})' % (callback,task_id))

    def addLog(self, ...):
        # 日志存入sql数据库,并返回log_id
        return log_id
   
    # 开始拉取文件,并记录日志
    def filepull_impl(self, log_id):
        try:
            # update 日志的状态为:执行中 ...
            cmd = ' -avzp /test [email protected]::home/ '   # rsync命令
            # -avzP --delete --password-file=/zyy/rsync-pc.passwd /zyy/test/* rsync://[email protected]:39001/zyytest
            status, result = self.rsync_exec(cmd)
            if status:
	    		# 修改日志状态为:'拉取成功',执行结果:'执行成功,总文件大小:%s' % result
            else:
                # 修改日志状态为:'拉取失败',执行结果:'同步未完成:%s' % result
            CURRENT_DUMP.pop(log_id)
        except Exception, e:
			# 修改日志状态为:'拉取失败',执行结果:'rsync error:%s' % e

    # 拉取文件的具体实现
    def rsync_exec(self, cmd):
        cmd = "/usr/bin/rsync %s " % (cmd)    #补充完整的rsync命令
        #Popen 是 subprocess的核心,子进程的创建和管理都靠它处理。
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        # 等待自动结束
        log_info=[]
        # 检查进程是否终止,如果终止返回 returncode,否则返回 None。
	    while p.poll() == None:
		    log=p.stdout.readline().strip()
		    if log!="":
		    	logging.info(log)
	    		log_info.append(log)
	    		CURRENT_DUMP[log_id].append(log)
        # 等待子进程终止
       	p.wait()
	    log_info.extend(p.stdout.readlines())  #有时程序退出了,但是管道还有数据
	    str='\n'.join(log_info)
        #执行完子进程状态,通常返回状态为0则表明它已经运行完毕,若值为负值 "-N",表明子进程被终。
	    if (p.returncode == 0):   
		# searchObj = re.search(r'total\s+size\s+is\s+(\d+)\s+speedup', str, re.M | re.I)
	    	searchObj = re.search(r'total\s+size\s+is\s+([\d\,]+)\s+speedup', str, re.M | re.I)
		    if searchObj:
		    	ll=searchObj.group(1).replace(',','')
		    	try:
		    		ll=int(ll)/1024
		    		return True,'%dKb'%ll
		    	except Exception,e:
		    		return True,ll
		    return False,str
	    return False,str

参数的参考链接:

Python3 subprocess | 菜鸟教程

Guess you like

Origin blog.csdn.net/cocos2dGirl/article/details/121127939