day27_subprocess模块
1、subprocess
通过代码执行操作系统的终端命令,并返回终端执行命令的结果
方法:
subprocess.Popen()
# 1 subprocess.Popen() 返回一个对象,对象的属性是执行命令的信息,如下
import subprocess
cmd = input('cmd>>:')
obj = subprocess.Popen(
cmd, # cmd命令
shell=True, # Shell=True 为True,才能控制终端,使用shell命令
stdout=subprocess.PIPE, # 返回正确命令的的执行结果,使用.read()方法读取为bytes
stderr=subprocess.PIPE # 返回错误命令的执行结果使用.read()方法读取为字符串bytes
)
print(f'obj:{obj}')
print(f'obj.stuout:{obj.stdout}')
print(f'obj.stderr:{obj.stderr}')
'''
'''
corect_cmd_result = obj.stdout.read()
err_cmd_result = obj.stderr.read()
print(f'type(corect_cmd_result):{type(corect_cmd_result)}')
print(f'type(err_cmd_result):{type(err_cmd_result)}')
# 因为是中文windows,所以使用gbk解码,即可得到字符串信息
corect_cmd_result = corect_cmd_result.decode('gbk')
err_cmd_result = err_cmd_result.decode('gbk')
print(f'corect_cmd_result:{corect_cmd_result}')
print(f'err_cmd_result:{err_cmd_result}')
# 由上面可知,obj.stdout.read() + obj.stderr.read() 代表所有的执行结果
restult = obj.stdout.read() + obj.stderr.read()
print(f"restult.decode('utf8'):{restult.decode('utf8')}")
# 因为read()方法只能读取一次,跟文件内读取文件机制类似,所以,需要将前面注释掉后才能读取
'''
cmd>>:notepad
obj:<subprocess.Popen object at 0x00000267CC5F4348>
obj.stuout:<_io.BufferedReader name=3>
obj.stderr:<_io.BufferedReader name=4>
type(corect_cmd_result):<class 'bytes'>
type(err_cmd_result):<class 'bytes'>
corect_cmd_result:
err_cmd_result:
restult.decode('utf8'):'''
subprocess.run()
# 2 subprocess.run() python3.5及以上版本,Run command with arguments and return a CompletedProcess instance
import subprocess
cmd = input('cmd>>:')
obj = subprocess.run(
cmd, # cmd命令
shell=True, # Shell=True 为True,才能控制终端,使用shell命令
stdout=subprocess.PIPE, # 返回正确命令的的执行结果,存储bytes数据
stderr=subprocess.PIPE # 返回错误命令的执行结果使用,存储bytes数据
)
print(obj)
result = obj.stdout + obj.stderr
# 需要注意的是run方法与Popen的区别,run得到的对象属性stdout和stderr就是bytes类型,不需要read()
print(result.decode('gbk'))
'''
cmd>>:notepad
CompletedProcess(args='notepad', returncode=0, stdout=b'', stderr=b'')'''
subprocess.getoutput()
# 3 subprocess.getoutput(cmd) 返回执行命令的结果,不管正确的还是错误的
import subprocess
cmd = input('cmd>>:')
result = subprocess.getoutput(cmd)
print(result)
'''
cmd>>:dir
驱动器 D 中的卷是 DATA
卷的序列号是 AE05-5DDC
D:\Python\python学习—上海老男孩\PycharmProjects\网络编程 的目录
2019/10/18 15:45 <DIR> .
2019/10/18 15:45 <DIR> ..
2019/10/18 15:44 <DIR> .idea
2019/10/18 15:45 186 test.py
2019/10/18 12:12 542 客户端.py
2019/10/18 12:13 874 服务端.py
3 个文件 1,602 字节
3 个目录 217,707,429,888 可用字节'''
2、实例
由客户端向服务器发送cmd命令,服务器执行命令,并将执行结果发给终端
# 客户端.py
import socket
client = socket.socket()
client.connect(('127.0.0.1',10086))
while True:
cmd = input('cmd>>:').encode('utf8')
client.send(cmd)
result = client.recv(1024).decode('gbk') # 指定接收数据的最大字节数1024
print(f'>>{result}')
if result == 'q':
break
# 服务器.py
import socket
import subprocess
server = socket.socket()
server.bind(('127.0.0.1', 10086))
server.listen(5)
while True:
conn, addr = server.accept() # 链接客户端
print(f'{addr}:')
while True:
try:
cmd = conn.recv(1024).decode('utf8')
print(f'from client:{cmd}')
if cmd == 'q':
conn.send(cmd.encode('utf8'))
break
# 1 subprocess.Popen()
obj = subprocess.Popen(
cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
restult = obj.stdout.read() + obj.stderr.read()
print(restult.decode('gbk'))
conn.send(restult)
print('to client success')
except Exception as e:
print(f'e:{e}')
break
conn.close() # 执行命令出错或者与该客户端的链接已断开