使用python处理shell命令(subprocess模块)
改模块的核心方法:
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(), * , encoding=None, errors=None)
args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:缓冲区大小。当创建标准流的管道对象时使用,默认-1。
0:不使用缓冲区
1:表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
正数:表示缓冲区大小
负数:表示使用系统默认的缓冲区大小。
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
cwd:用于设置子进程的当前目录。
env:用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承。
subprocess模块主要用于创建子进程,并连接它们的输入、输出和错误管道,获取它们的返回状态。通俗地说就是通过这个模块,你可以在Python的代码里执行操作系统级别的命令
大多数情况下,推荐使用run()方法调用子进程,执行操作系统命令。在更高级的使用场景,你还可以使用Popen接口。其实run()方法在底层调用的就是Popen接口。
执行终端命令,并将命令的输出定向输出到subpracess管道中(使用subprocess.run)
data = subprocess.run(["ls -a"], shell=True, stdout=subprocess.PIPE)
# 在终端中执行 ls -a 命令,然后将命令的标准输出定向输出到管道中,其中data用来接收输出结果
f.write(data.stdout.decode("GBK"))
#将输出结果写入指定文件中,其中f为文件描述符,在获取输出结果时,使用data.stdout.decode("GBK")来获取输出。
关于UTF-8和GBK
UTF-8: 解决国际上一种多字节编码,其中对英文使用单字节(8位)编码,对中文采用3字节(24位)编码
GBK: 包含所有中文字符,其中对中文和英文都使用2字节编码(16位)
subprocess.popen()
对于一些不单单只是得到指令执行结果,而对于一些交互式的命令,比如需要输入一些东西可以使用subprocess.popen()
subprocess.popen()的返回值是一个Popen对象,而不是CompletedProcess对象。
使用popen()命令完成对终端命令的执行并写入指定文件
s = subprocess.Popen("ls -a", stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
s.stdin.write(b"import os\n") # 将import os\n输入到管道中,
out = s.stdout.read().decode("GBK") # 将命令的结果进行输出。
# 通过s.stdin.write()可以输入数据,而s.stdout.read()则能输出数据。