Python相关的基础模块
在编写远程控制工具之前,先要介绍用Python编写远程控制工具时所需要的 相关模块,为接下来编写工具打下基础。
1.subprocess模块
subprocess模块的主要作用是执行外部的命令和程序。当我们运行Python的时 候,其实也是在运行一个进程,而用subprocess模块可以创建一个子进程来执行命 令。
subprocess模块包含许多创建子进程的函数,这些函数分别以不同的方式创建 子进程,我们可以根据需要来从中选取一个使用。另外,subprocess还提供了一些 管理标准流(standard stream)和管道(pipe)的工具,从而实现在进程间使用文 本通信。
(1)subprocess.call(args ,* ,stdin=None ,stdout=None ,stderr=None, shell=False ,cwd=None ,timeout=None)
其中,args参数可以接收一个数组或字符串来作为运行命令。若args为数组, 则需要将命令和参数分开,否则会出现No such file or directory错误。
当args接收的参数为数组,且格式正确时,会输出命令执行结果并返回0:
当args接收的参数为数组,但是命令和参数没有分开时,会报错:
若args接收的参数为字符串时,需要让shell为True 。这样subprocess.call() 函数会把接收到的字符串当作命令并调用shell去执行,成功执行后返回执行结果 并返回0 ,如下所示:
仔细观察会发现subprocess.call() 函数在执行完由args指定的命令后,会有 返回值0 。这里返回值为0 ,就表示命令执行成功(return code ,0表示成功,非0 表示失败)。
stdin 、stdout 、stdeer分别表示程序的标准输入、输出、错误句柄。它们可以 是PIPE 、文件描述符或文件对象,默认值为None ,表示从父进程继承。本章不会 用到这几个参数,所以不展开讲解。
(2)subprocess.check_call(args ,* ,stdin=None ,stdout=None, stderr=None ,shell=False ,cwd=None ,timeout=None)
该函数与subprocess.call() 函数类似,不同之处在于subprocess.check_call会 对返回值进行检查。如果返回值非0 ,则会抛出CallProcessError异常。
subprocess.CalledProcessError异常包括returncode 、cmd 、output等属性,其中
returncode是子进程的退出码,cmd是子进程的执行命令,output为None 。具体使 用案例如下所示。
当subprocess.call执行成功时,会显示执行结果并返回0:
当subprocess.call执行失败时,会抛出CallProcessError异常:
可以通过try …except …语句来捕获CallProcessError异常,并分别打印输出 returncode 、cmd 、output的内容:
(3)subprocess.check_output(args ,* ,stdin=None ,stderr=None, shell=False ,cwd=None ,encoding=None ,errors=None,
Universal_newlines=None ,timeout=None ,text=None)
subprocess.check_output() 函数与前面两个函数的主要区别在于它会以字符 串形式返回执行结果的输出。这个函数同样会进行返回值检查,若returncode不为 0 ,则会抛出subprocess.CalledProcessError异常,效果如下所示:
2.Struct模块
接下来,我们介绍另一个模块—— Struct模块。这个模块主要用于解决Socket 传输数据时粘包的问题。在Python中只定义了6种数据类型:数字、字符串、列 表、元组、字典、集合,但是没有定义字节类型的数据,因此在Socket数据传输 中需要转换为字节流。
在传送文件前,通过这个模块将文件的属性(文件大小)按照指定长度转换 打包,发送给对端计算机。对端计算机先接收这个固定长度的字节内容来查看接 下来要接收的文件的大小是多少,那么最终接收的数据只要达到这个大小,就说 明文件接收完毕,以此解决Socket文件传输粘包问题。
这里用到的函数主要为pack() 、unpack() 和calcsize() 。转换的操作格 式如表11-1所示。
表11-1 format格式
(1)struct.pack(format ,v1 ,v2 ,...)
该方法返回一个bytes对象,其中包含格式字符串format以及打包的值v1, v2 , ⅆ , 参数个数必须与格式字符串所要求的值完全匹配,如下所示:
(2)struct.unpack(format ,buffer)
该方法根据格式字符串format从缓冲区buffer解包(假定是由
pack(format ,... )打包)。结果为一个元组,即使其只包含一个条目,如下所 示:
(3)struct.calcsize(format)
该方法计算格式字符串所对应的结果的长度,如下所示: