10月20日subprocess模块

发布时间 2023-10-20 15:45:49作者: songjunwan

subprocess模块

这个模块的作用在于执行系统命令的模块

首先需要将这个模块导入

然后有一个固定的格式:

obj = subprocess.Popen('dir', shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

这里的obj只是一个名可以修改,后面的是重点,Popen是一个标准的模块,用于创建新的进程并与其进行交互,可以这么理解它是用来执行系统命令、脚本或其他可执行文件。

这里的'dir'是windows里面的终端命令,注意这个终端命令要以字符串的形式

剩下的三个要是没有固定要求就锁死,就这么写

shell=Truesubprocess.Popen 的一个参数,用于指定是否通过 shell 来执行命令。当 shell=True 时,你可以将命令作为一个字符串传递,就像在命令行中一样。(这个固定写死)

subprocess.PIPE: 用于创建管道的格式,这个管道是将输出的结果保存到这里。(还有一个与之对应的格式暂时了解即可,subprocess.DEVNULLsubprocess 模块中的一个特殊文件句柄,通常用于在执行子进程时将标准输入、标准输出或标准错误重定向到一个空设备。)

标准输出 (stdout)用于正常的命令输出,通常包括程序的结果或一般信息。

标准错误 (stderr)用于报告错误消息和警告,通常包括程序执行时的问题。

实际操作一下

# subprocess执行系统命令的模块
import subprocess

#执行系统dir命令,把执行的正确结果放到管道中
obj = subprocess.Popen('dir', shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#subprocess.PIPE就是用于存储正确信息的管道,然后这里的obj是此管道的名称

lis = subprocess.Popen('tasklist',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#这里的tasklist是Windows操作系统中的命令行工具。用于查看正在使用的软件情况以及名称


#拿到正确结果的管道,读出里面的内容
ss=obj.stdout.read()#这里把管道(dir)里的数据赋值给ss来进行读取
print(ss.decode('utf-8'))#这里再把数据解码成utf-8

ll = lis.stdout.read()#这里把管道(lis)里的数据赋值给ll进行读取
print(ll.decode('utf-8'))#这里再把数据解码成utf-8

结果如图

这里为什么还有解码呢?因为windows用的是gbk编码所以要把数据解码成utf-8编码

现在把这个模块运用到服务器与客户端中

首先是服务器

import socket
import subprocess
# 生成一个socket对象
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址跟端口号
soc.bind(('172.17.8.49', 8080))
# 开启服务器
soc.listen(3)

# 先来一个等待连接循环
while True:
    print('等待客户端连接')
    # 等候客户端来连接,conn相当于连接通道,addr是客户端的地址
    conn, addr = soc.accept()
    print('有个客户端连接上了', addr)  # 这里显示客户端的IP地址以及端口
    # 这里再写一个接收客户的循环
    while True:
        try:
            data = conn.recv(1024)  # 将收到的客户端数据赋值给data

            if len(data) == 0:
                break
            print(data)
            obj = subprocess.Popen(str(data,encoding='utf-8'),shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            #这里建立一个存放命令的通道

            #这里把通道的数据读取然后赋值给shiyong
            shiyong = obj.stdout.read()
            #把执行的结果通过网络传给客户端
            conn.send(shiyong)
        except Exception:
            break#这里终止的是这个接收循环


    # 关闭与客户端的接口
    conn.close()


# 关闭服务器唯一的接口
soc.close()

结果

然后是客户端

import socket
soc = socket.socket()
soc.connect(('172.17.8.49', 8080))
while True:
    fasong = input('请输入要执行的命令:')
    #还需要将发送的数据进行编码
    soc.send(fasong.encode('utf-8'))
    #这里接收来自服务器传回来的命令结果
    data = soc.recv(1024)
    print(str(data, encoding='utf-8'))#尽量用utf-8来解码,能预防解码失误到时传输失败

结果