关于安全性:使用os.system(“bash code”)在Python脚本中调用bash命令是否很好?

Is it good style to call bash commands within a Python script using os.system(“bash code”)?

我想知道在使用os.system()的Python脚本中调用bash命令是否被认为是一种好的风格。我还想知道这样做是否安全。

我知道如何在bash和python中实现我需要的一些功能,但是在bash中实现它要简单得多,而且更直观。但是,我觉得编写os.system("bash代码")非常黑客。

具体来说,我想将以某个扩展名结尾的所有文件移动到一个目录中。

在bash中:*mv.ext/path/to/destination在python(伪代码)中:对于目录中的文件:如果file.endswith("ext"):将文件移动到目标

在这种情况下,我应该怎么做?


首先,您的示例使用mv,它是coreutils中的程序,而不是bash。

使用os.system()调用外部程序被认为是糟糕的风格,因为:

  • 您正在创建特定于平台的依赖项
  • 您正在创建特定于版本的依赖项(是的,甚至coreutils有时也会更改!)
  • 您需要检查是否存在外部命令(以及它们是否在$path中,以及是否可由用户执行等)。
  • 必须使用返回代码对命令进行错误检查。在语言错误代码或异常中使用更好。(os.system()不允许分析stdout/stderr)
  • 您必须自己处理用空格引用变量(或将其转义)。
  • python已经通过提供库为您完成了这项工作!

像其他人已经提到的,查找glob,寻找shell-like模式匹配(globbing)和shutil。否则,您所需要的一切都已经在标准库中了。

1
2
3
4
5
import glob
import shutil

for extfile in glob.glob('*.ext'):
    shutil.move(extfile,dest)

此外,不应使用os.system()—而是查看子进程模块。


查看python的shutil模块。它提供文件系统操作,如移动文件。在这个模块和os模块之间,您应该拥有所需的所有工具。因为其他人说的原因,这比bash命令更好。


使用Python函数来完成这类工作总是更好、更好的风格。对于Python来说,用独立于操作系统的方式编写脚本而不是使用bash并不难。


为什么要使用纯Python,

  • 通过使用python,您已经假设安装了python和标准库。通过在python内部使用bash代码,您可以做出这个假设,再加上安装了bash并在系统路径上的假设。
  • 通过使用两种语言的组合,您将使代码更难被其他人阅读(并非每个人都知道Python和Bash)。
  • 如果你用python的方式做的话,在没有长代码行的情况下会感觉更自然一些。
  • 在这种情况下,我会用…

    1
    2
    3
    4
    import os
    for filename in os.listdir('.'):
      if filename.endswith('.ext'):
        os.rename(filename, os.path.join('path', 'to', 'new', 'destination', filename))

    不过,也许还有更好的方法


    仅引用问题就意味着最好使用纯Python解决方案。


    这不是主意,因为它让你的脚本更不易移植。本机python脚本可以在安装了正确python库的任何UNIX或Windows计算机上运行。当您将shell命令添加到混合中时,您将打破这个限制,并突然被锁定到一个更窄的子集中。

    有时您没有选择,但是如果是这样简单的事情,那么用Python编写本机代码会更有意义,而且启动速度更快(因为Python进程不必仅仅为了执行一个命令而生成一个新的shell)。


    通常,python提供了"子进程"模块,允许您运行命令并对其输出进行广泛的控制。它允许您"生成新进程,连接到它们的输入/输出/错误管道,并获取它们的返回代码":

    http://docs.python.org/library/subprocess.html