Python 执行 shell 命令的常用方式
在使用 Python 编写自动化脚本的时候,难免会需要执行一些基本的 shell 命令,而 Python 执行 shell 命令的方式有好几种,如果根据需要选择最适合的方式显得非常重要,这篇文章总结和对比一下几种常见的 Python 运行 shell 命令的方式。
os.system()
os.system()
可以说是最为基本的运行shell命令的方式了,这个方法的特点就是直接运行命令,并将运行之后的状态值返回码返回,所以结果是一个 int 类型,这个方式比较常见是运用在只需要执行 shell 命令而不需要得到命令的返回结果的场景。
比如执行一个创建目录的操作就可以执行实用这个方法:
1 | >>> import os |
这个例子可以看到,当命令执行成功的时候可以返回0,而执行失败则返回的是256,所以可以根据返回码来判断命令是否执行成功。
os.popen()
os.popen()
方法执行命令之后会把成功执行的命令的结果以文件的形式返回,所以可以通过 read()
方法获取执行的结果,而如果执行失败,则文件为空,所以这个方法的适用场景是命令返回的结果比较多,需要进行提取结果的场景。
1 | >>> import os |
commands 模块
commands 模块(不是自带模块)主要常用的是下面两个方法:
commands.getstatusoutput(cmd)
返回(状态码, 输出结果)commands.getoutput(cmd)
只返回输出结果
这个模块看起来就比较完善了,可以同时得到执行的状态码和输出结果,可以说是同时具备了 os.system()
和 os.popen()
的功能,实用性更强一些。
1 | >>> import commands |
上面的执行例子可以看到,commands.getstatusoutput(cmd)
方法的执行结果是一个元组,第一个结果是状态码,第二个是输出结果的字符串格式,所以如果想要在提取执行结果的同时获取到执行的成功与否,则可以直接使用这个方法。
subprocess 模块
subprocess
模块是官方比较推荐的模块,基本可以取代上面的三种方法,功能也更加强大,可以满足大部分的场景。
subprocess.call() 相当于 os.system() 命令的用法,它执行命令并将执行结果状态码返回。
直接看下面例子:
1 | >>> import subprocess |
subprocess 模块里面的方法执行 shell 命令的时候如果传入的命令是字符串的形式,那必须将参数 shell 设置为 True,不然默认就是使用的列表作为命令的传入参数,比如看下面这种不设置 shell=True 和设置的对比:
1 | >>> res1 = subprocess.call(['ls', '-l']) |
可以看到,当不设置 shell=True
的时候,必须将命令分解成列表传入才能执行,这个据说是为了安全起见所以默认是关闭字符串执行的,不过在工作中使用的时候当然都是用字符串的方式执行了。
subprocess.Popen()
方法是我们项目代码中使用的,这个方法同样是可以输出执行的状态码和输出结果,但是参数比 commands 需要的多。
1 | >>> cmd = "cd /tmp && mkdir tt6 && ls" |
使用 communicate()
方法可以得到执行结果的成功输出和报错输出,如果没有报错则报错为空字符串。
总结
以上就是常见的 Python 执行 shell 命令的方法,当然,上述都是内置库,也有第三方库可以实现 shell 执行,但是并不建议使用,毕竟官方提供的内置库已经可以满足大部分场景。我的建议是当执行的命令比较简单而且也不是经常调用的时候,可以直接使用 os.system(),而如果是需要把执行命令的方法写到函数中经常性的调用,则应该使用 subprocess.Popen()
这种更加高级的方法。