在Python中,open(file).read()和subprocess(['cat',file])之间有什么区别,并且优先于另一个吗?

Jac*_*ips 4 python

假设我要从中读取RAM使用情况/proc/meminfo。我可以想到两种基本方法。

使用shell命令

output = subprocess.check_output('cat /proc/meminfo', shell=True)
# or output = subprocess.check_output(['cat', '/proc/meminfo'])
lines = output.splitlines()
Run Code Online (Sandbox Code Playgroud)

使用open()

with open('/proc/meminfo') as meminfo:
    output = meminfo.read()
lines = output.splitlines()
Run Code Online (Sandbox Code Playgroud)

我的问题是两种方法有什么区别?有明显的性能差异吗?我的假设是使用open()是首选方法,因为使用shell命令有点hacker,并且可能与系统有关,但是我找不到关于此的任何信息,所以我想问一下。

Cha*_*ffy 5

...所以,让我们看一下output = subprocess.check_output('cat /proc/meminfo', shell=True)它的作用:

  • 使用创建一个FIFO对mkfifo(),并生成一个运行中的Shell,sh -c 'cat /proc/meminfo'将其写入FIFO的输入端(而Python解释器本身则通过select()调用或阻塞IO操作监视另一端的输出)。这意味着打开/bin/sh,打开它依赖的所有库等。
  • Shell将这些参数解析为代码。如果不打开就可能很危险/proc/meminfo。你却开门了/tmp/$(rm -rf ~)/pwned.txt
  • Shell派生了一个子进程(可选; Shell可能具有一个隐式exec),然后使用execve系统调用以/bin/catargv- 进行调用,这['cat', '/proc/meminfo']意味着该参数/bin/cat将再次作为可执行文件及其动态库加载,而所有性能开销意味着。
  • /bin/cat然后打开/proc/meminfo,从中读取并写入其标准输出
  • 如果外壳程序未使用隐式exec优化,则将/bin/cat使用wait()-family syscall 等待可执行文件完成并退出。
  • Python解释器从FIFO的远程端读取数据,直到它提供EOF(直到cat关闭其输出管道(可能是通过退出)之后才会发生),然后使用wait()-family调用来检索有关其如何生成外壳的信息退出,检查退出状态以确定是否发生错误。

现在,让我们看一下open('/proc/meminfo').read()它的作用:

  • 使用open()syscall 打开文件。
  • 使用read()syscall 读取文件。
  • 删除文件上的引用计数,以使其可以通过close()syscall 关闭(立即或在以后的垃圾回收过程中)。

这些事情之一是很多,很多很多更有效和普遍比其它敏感。