Python_多进程_subprocess(含标准输入、输出、错误输出)
多进程_subprocess
一、说明
subprocess为新启动的子进程,不是主进程
cmd的命令的返回结果,会存进pip所在的缓存区域里
统计文件有多少行 wc -l a.txt
ls -al|wc -l#ls的命令执行的结果通过管道流给了wc命令去使用
#ls的结果存在了缓存区域,后面的命令可以直接在缓存里取到
>>> import subprocess >>> a = subprocess.Popen('mkdir subprocesstest',shell=True,cwd='e:\\test')#Popen,cwd是当前路径下
#参数说明:shell命令;是否用shell命令执行;路径
二、实例:列出文件目录的内容
1、Windows下执行:
subprocess.run(args=['dir','test'],shell=True,cwd="e:\\")#dir是命令,后面的test是参数
运行结果:
2、linux下执行
subprocess.call("ls -l",shell=True,cwd="/home")
三、Subprocess 模块的基本使用方法(通过管道执行python命令)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) obj.stdin.write(b"print(1);")#无;会有报错 obj.stdin.write(b"print(2);")#无; obj.stdin.write(b"print(3);")#无; obj.stdin.write(b"print(4);")#无; obj.stdin.close() cmd_out = obj.stdout.read() obj.stdout.close() cmd_error = obj.stderr.read() obj.stderr.close() print(cmd_out) print(cmd_error)
运行结果:(print代码行有误时:无;)
运行结果:(print代码行正确时:有;)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) obj.stdin.write(b"print(1)\n") obj.stdin.write(b"print(2)\n") obj.stdin.write(b"print(3)\n") obj.stdin.write(b"print(4)\n") obj.stdin.close() cmd_out = obj.stdout.read() obj.stdout.close() cmd_error = obj.stderr.read() obj.stderr.close() print(cmd_out) print(cmd_error)
运行结果:
另一种写法
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) obj.stdin.write(b"print(1)\n") obj.stdin.write(b"print(2)\n") obj.stdin.write(b"print(3)\n") obj.stdin.write(b"print(4)\n") out_info,out_error = obj.communicate()#简单写法,out_info:标准输出 print(out_info,out_error)
运行结果:
四、 linux下执行两个命令:
import subprocess child1 = subprocess.Popen(["cat","/home/wxh/a.py"], stdout=subprocess.PIPE) child2 = subprocess.Popen(["wc","-l"],stdin=child1.stdout, stdout=subprocess.PIPE)#输入内容是子进程1的输出内容
out = child2.communicate() print(out)
运行结果:
五、Subprocess进程通信实例
import subprocess import os class Shell(object) : def runCmd(self, cmd) : res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # 获取子进程的标准输出,标准错误信息 sout, serr = res.communicate() #sout:执行命令后的输出内容,serr出错内容,res.pid为进程编号 return res.returncode, sout, serr, res.pid shell = Shell() fp = open('e:\\ip.txt', 'r',encoding="utf-8") ipList = fp.readlines() fp.close() fp = open('e:\\ping.txt', 'a',encoding="utf-8") print(ipList) for i in ipList : i = i.strip() result = shell.runCmd('ping ' + i) if result[0] == 0 : w = i + ' : 0' fp.write(w + '\n') else : w = i + ' : 1' fp.write(w + '\n') #print( result[1].decode("gbk")) fp.close()
数据文件内容:
Ip.txt
www.baidu.com
www.taobao.com
123.45.5.34
127.0.0.1
六、设置日志输出到控制台
#encoding=utf-8 import multiprocessing import logging import sys def worker(): print('I am working....') sys.stdout.flush()#让日志信息立即输出,一般是累积到一定程度之后才输出
if __name__ == '__main__': # 设置日志输出到控制台 multiprocessing.log_to_stderr() logger = multiprocessing.get_logger() # 设置输出日志的级别(info/error) logger.setLevel(logging.INFO) p = multiprocessing.Process(target = worker) p.start() p.join()
运行结果参照:
七、守护进程(子进程、主进程共同进退)
#encoding=utf-8 import multiprocessing import time, logging import sys
#守护进程的方法 def daemon(): p = multiprocessing.current_process() print('Starting:', p.name, p.pid) sys.stdout.flush() # 将缓冲区数据写入终端 # time.sleep(2) print('Exiting :', p.name, p.pid) sys.stdout.flush()
#非守护进程的方法 def non_daemon(): p = multiprocessing.current_process() print('Starting:', p.name, p.pid) sys.stdout.flush() print('Exiting :', p.name, p.pid) sys.stdout.flush() if __name__ == '__main__': # 设置日志输出到控制台 multiprocessing.log_to_stderr() logger = multiprocessing.get_logger() # 设置输出日志的级别 logger.setLevel(logging.DEBUG) d = multiprocessing.Process(name='daemon', target=daemon) d.daemon = True#是守护进程 n = multiprocessing.Process(name='non-daemon', target=non_daemon) n.daemon = False#非守护进程 d.start() time.sleep(1) n.start() # d.join(1) # n.join() print('d.is_alive()', d.is_alive()) print("n.is_alive()", n.is_alive()) print("main Process end!")
运行结果: