subprocess应用:python原样输出linux信息以及poll()返回值判断
一. subprocess输出shell命令的值
方法1:
#!/usr/bin/python3 # -*- coding: utf-8 -*- import os import subprocess # 与在命令窗口执行显示效果相同,如有彩色输出可保留,但不能返回结果 def run(command): subprocess.call(command, shell=True) # 实时输出但不可显示彩色,可以返回结果 def sh(command, print_msg=True): p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lines = [] for line in iter(p.stdout.readline, b''): line = line.rstrip().decode('utf8') if print_msg: print(">>>", line) lines.append(line) return lines #print('run():') #run("ping www.baidu.com") #cmd = 'certbot certonly --no-self-upgrade -d "*.smartfleet.inhandiot.com" -d "smartfleet.inhandiot.com" --manual --preferred-challenges dns --dry-run --manual-auth-hook "/root/workshop/certbot/au.sh python aly add" --manual-cleanup-hook "/root/workshop/certbot/au.sh python aly clean"' print('\n\nsh():') sh("free -h") #sh(cmd)
写入文件
>>> fdout=open("/tmp/ifconfig.log", 'a') >>> fderr=open("/tmp/ifconfig-error.log", 'a') >>> p=subprocess.Popen("ifconfig", stdout=fdout, stderr=fderr, shell=True) >>> p.wait()
从文件中取某行,这里取最后一行为例
#1. 从文件中取到最后一行 >>> os.popen("cat /tmp/test11.log").readlines()[-1].strip() 或者 with open("/tmp/test11.log", mode="r", encoding="UTF-8") as fd: x=fd.readlines()[-1] print(x)
方法2:
import subprocess
def run_shell(shell):
cmd = subprocess.Popen(shell, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, shell=True, bufsize=1) # 实时输出 while True: line = cmd.stdout.readline() print(line, end='') if not line: break return cmd.returncode if __name__ == '__main__': print(run_shell("ping www.baidu.com"))
universal_newlines: 各种换行符都统一处理为"\n"
bufsize=1: 表示行缓冲
方法3
.readline可能导致卡死,官方推荐使用communicate,但是如果还是使用subprocess.PIPE,执行完命令后才能拿到标准输出,替换成sys.stdout就能达到实时输出效果,代码附上
import subprocess import sys def run_shell(shell): cmd = subprocess.Popen(shell, stdin=subprocess.PIPE, stderr=sys.stderr, close_fds=True, stdout=sys.stdout, universal_newlines=True, shell=True, bufsize=1) cmd.communicate() return cmd.returncode if __name__ == '__main__': print(run_shell("ping www.baidu.com"))
https://www.cnblogs.com/chenqionghe/p/11532245.html
https://www.jb51.net/article/201484.htm
二. subprocess是否执行成功的状态返回值
本例以一个不存在的目录为例,来测试状态返回值
import subprocess p = subprocess.Popen("ls /root", stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, shell=True, bufsize=1) err_msg=p.stderr.read() print("错误输出为:",err_msg) cmd_status=p.poll() print(cmd_status) # 目录为/root时返回0, 目录为不存在的/abc时返回2
while True: line = p.stdout.readline() print(line) if not line: break #return cmd_status
测试代码如上,poll函数返回码:
0 正常结束 1 sleep 2 子进程不存在 -15 kill None 在运行
努力生活,融于自然