我无法找到答案的简单问题:
除代码可移植性之外,使用os.mkdir("somedir")
优于os.system("mkdir somedir")
或subprocess.call()
是否有好处?
答案应该适用于Python 2.7。
编辑:有人提出硬编码目录与变量(可能包含用户定义数据)引入了安全问题。我最初的问题是来自系统方法(即幕后发生的事情),但安全问题是一个有效的问题,在考虑完整的答案时应包括在内,以及包含空格的目录名
答案 0 :(得分:12)
考虑如果您的目录名称包含空格会发生什么:
mkdir hello world
...创建两个目录,hello
和world
。如果您只是盲目地用引号替换,那么如果您的文件名包含引用类型,则无效:
'mkdir "' + somedir + '"'
... somedir
包含hello "cruel world".d
时效果不错。
以下情况:
os.system('mkdir somedir')
...考虑如果您替换somedir
的变量被称为./$(rm -rf /)/hello
会发生什么。
此外,调用os.system()
(或subprocess.call()
与shell=True
)调用shell,这意味着您可以对ShellShock等错误开放;如果您的/bin/sh
是由ShellShock易受攻击的bash提供的,并且您的代码提供了任意机制来存在任意环境变量(通过CGI的HTTP标头的情况),这将为代码注入提供机会。
os.system('mkdir somedir')
...启动一个shell:
/bin/sh -c 'mkdir somedir'
...然后需要链接和加载;需要解析其论点;并且需要调用外部命令 mkdir
(意思是另一个链接和加载周期)。
以下是一项重大改进:
subprocess.call(['mkdir', '--', somedir], shell=False)
...只调用外部mkdir
命令,没有shell;但是,因为它涉及fork()/ exec()循环,这仍然是对C库mkdir()
调用的显着性能损失。
在os.mkdir(somedir)
的情况下,Python解释器直接调用适当的系统调用 - 根本没有外部命令。
如果你致电os.mkdir('somedir')
但它失败了,你会得到一个IOError
抛出适当的errno
,并且可以轻易地确定错误的类型。
如果mkdir
外部命令失败,则会出现失败的退出状态,但如果没有解析其stderr(这是为人类编写的,而不是机器可读性,内容会有所不同),则无法处理实际的基础问题取决于系统的当前区域设置。)