使用 split() 拆分命令行有什么问题吗?



"如何运行外部命令"问题的大多数答案中,我看到了

如果你想运行ls -l,你需要使用subprocess.call(["ls", "-l"])

当我知道我将要运行什么时,我通常会调用subprocess.call('ls -l'.split(' ')),以直观地将命令行整合在一起(它通常是一个变量)。

使用split()与手动构建列表(同样,当命令已知时)相比,是否存在固有的错误。还是这些答案是为了明确地表明需要一个列表?

我试图找到一些缺点(多个空格、转义空格等),但我不知道这种方法哪里会出错?

注意:这个问题特别是关于空间拆分的稳健性,而不是安全问题或其他(非常重要的)考虑因素。

注意这是有效的:

>>> import subprocess
>>> subprocess.call(['ls', '-l', "my file"])
-rw-rw---- 1 john john 0 May  5 10:46 my file
0

但事实并非如此:

>>> subprocess.call('ls -l "my file"'.split(' '))
ls: cannot access "my: No such file or directory
ls: cannot access file": No such file or directory
2

这确实有效:

>>> import shlex
>>> shlex.split('ls -l "my file"')
['ls', '-l', 'my file']
>>> subprocess.call(shlex.split('ls -l "my file"'))
-rw-rw---- 1 john john 0 May  5 10:46 my file
0

建议

在python哲学中,显式优于隐式。因此,在这三种形式中,使用以下一种:

subprocess.call(['ls', '-l', 'my file'])

这避免了所有的预处理,并明确无误地向您展示了将执行的内容及其参数。

如果您真的确信无转义字符(包括文件名中的空格)没有问题,那么我认为没有任何问题。

但您可能会发现使用os.system("ls -l")更容易。只需注意,如果你想使用结果代码,它应该右移8位:

exit_code = os.system("ls -l") >> 8

或者(更健壮,但也需要更多的打字工作…):

subprocess.call('ls -l', shell=True)

然后让shell处理拆分。

编辑:同时提及子流程。

最新更新