使出Python的六脉神剑,让Python拥有无限扩展性

为了让更多的人看到本文,请各位读者动动小手,点击右上角【...】,将本文分享到朋友圈,thanks! 

咱们知道,Python的API很是多,功能很是强大,并且很是易用。Python之因此强大,一个重要缘由是由于Python很是容易与其余编程语言交互。这就让Python拥有了无限扩展性。就算Python没法实现某个功能,能够用其余语言实现,而后Python直接调用便可。
Python与其余编程语言交互,主要有以下两种方法:
(1)调用动态库,如.dll,.so等;
(2)直接执行外部命令,并接收外部命令的返回结果;
第1种方法我会在后面的文章中详细讨论,本文主要讲解如何使用Python执行外部的命令,并传递参数和接收返回值,而后作更进一步的处理。本文将介绍6种执行外部命令的方法,并比较这6中方法的优缺点。史称这6种执行外部命令的方法为六脉神剑。
Python执行外部命令的6种方法:
1. system函数
基本的调用格式以下:
import osos.system("some_command with args");
system函数会将命令和参数传递给系统的Shell。这么作很是好,由于您实际上能够用这种方式一次运行多个命令,并设置管道和输入/输出重定向。例如:
import osos.system("cat command.py | grep -n subprocess > result.txt")
执行这段代码,会在当前目录生成一个result.txt文件。
尽管这样作很方便,但必须手动处理转义字符(例如空格等)。因此这样作只是让你简单地运行Shell程序,而不是扩展程序的功能。
2.  popen函数
基本调用格式以下:
import osstream = os.popen("some_command with args")
popen函数与os.system函数的功能相同,只是popen函数提供了一个用于操做文件的对象,可用使用标准输入输出的方式来访问文件中的数据。popen函数还有其余3种变体,它们对I/O的处理略有不一样。若是将全部内容都做为字符串传递,那么命令将传递到Shell程序;若是将它们做为列表传递,则无需担忧转义任何内容。例如:
import osstream = os.popen("cat command.py | grep -n subprocess")print(type(stream))result = stream.readlines()print(type(result))print(result)
执行这段代码,会输出以下内容:
<class 'os._wrap_close'><class 'list'>['1:import subprocess\n', '2:subprocess.run(["ls", "-l"])\n', '5:subprocess.call(["ls", "-l"])\n', '8:os.system("cat command.py | grep -n subprocess > result.txt")\n']
咱们能够看到,readlines方法以列表形式返回命令的执行结果。

3. Popen类
subprocess模块的Popen类。该类可用于替换os.popen函数。但Popen类的缺点是因为功能过于强大,因此使用起来稍微复杂一些。例如:
print(subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read())
这行代码能够用来替换下面的代码:
print(os.popen("echo Hello World").read())
关于Popen类的一个更复杂的例子以下:
import subprocessp = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)for line in p.stdout.readlines(): print(line.decode("utf-8").strip())retval = p.wait()
这段代码经过标准输出的readlines方法读取了ls命令返回结果的全部行,并将这些内容输出到Console。最后用wait方法等待ls命令执行完,最后结束程序。
Popen类相对于popen函数的优点是将全部的选项都统一放在了Popen类中,而不是须要4个不一样的popen函数完成这些工做。
4.call函数
来自subprocess模块的call函数。与Popen类同样,拥有相同的参数,但call函数只会等待命令执行完并提供返回代码才结束。例如:
return_code = subprocess.call("echo Hello World", shell=True)print(return_code)
5. run函数
若是读者使用的是Python 3.5或更高版本,则能够使用新的subprocess.run函数,该函数与上面的代码很是类似,可是更加灵活,并在命令完成执行后返回CompletedProcess对象。例如:
import subprocessresult = subprocess.run(["ls", "-l"])print(type(result))

6. 类C函数
os模块还提供了与C语言相似的fork / exec / spawn函数,可是我不建议直接使用它们,例如:
import osprint(os.execl('/bin/ls', ' '))
最后,请注意,对于这些执行外部命令的方法,须要将这些命令执行后参数的字符串传递回程序,有时须要对这些传回的字符串进行转移。若是你没法彻底信任这些字符串,那么有可能会带来严重的安全隐患。例如,若是用户正在输入字符串的某些/任何部分。若是不肯定,请仅将这些方法与常量一块儿使用。为了更好地说明这一点,请看下面的代码。
print(subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read())
咱们能够想象,当用户输入了“I love your harddisk && rm -rf /”,这将删除硬盘中的全部数据。因此若是你对用户的输入没法彻底信任的话,请将变量user_input改为常量,不让用户任意输入。

- EOF -python

推荐阅读   点击标题可跳转

1. 开发跨设备的鸿蒙(HarmonyOS) Appweb

2.鸿蒙(HarmonyOS)大神都喜欢玩命令行typescript

3.像极客同样提取Android的Root权限shell

4.牛掰了!鸿蒙与Android完美融合,将鸿蒙设备当Android设备用
编程

5.【鸿蒙学院】鸿蒙App开发直播学员提问与回答swift


关注「极客起源」公众号,加星标,不错过精彩技术干货
安全


本文分享自微信公众号 - 极客起源(geekculture)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。bash

相关文章
相关标签/搜索