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()  # 执行命令出错或者与该客户端的链接已断开

posted @ 2019-10-20 22:58  W文敏W  阅读(114)  评论(0编辑  收藏  举报