使用subprocess.Popen与os.popen执行命令“ls -d * /”

时间:2015-12-29 22:45:44

标签: python linux

在Linux OS上,下面的python代码提供了当前目录中的目录。

dirs = os.popen('ls -d */').read().split(os.linesep)
print dirs

由于不推荐os.popen,我将此调用迁移到subprocess.Popen

proc = subprocess.Popen(['ls', '-d', '*/'], stdout=subprocess.PIPE)
outp = proc.stdout.read()
print outp

但由于某些原因,这不起作用,我收到以下错误

ls: cannot access */: No such file or directory

1 个答案:

答案 0 :(得分:4)

*/仅在执行globbing时才有效;在os.popen中,整个字符串由一个包含实际ls进程的shell进行评估,而shell正在执行扩展。当您使用基于list的{​​{1}}时,它会将文字字符串Popen传递给*/,并且ls不会自行展开全局。

您可以将lsstr传递给shell=True,但这只会重新打开Popen所具有的性能,安全性和稳定性漏洞。更容易避免子进程,只需使用glob moduleos.popen / os.scandir / os.listdir之一,而不是使用子进程。

例如,在带有os.scandir的Python 3.5中,您可以非常有效地获取工作目录中的所有目录:

os.walk

在早期版本的Python上,import os dirs = [x.name for x in os.scandir() if x.is_dir()] + os.listdir可以用来做同样的事情,效率稍差(它涉及os.path.isdir每个条目的stat os.scandir避免,但对于小目录和/或本地文件系统,stat成本是微不足道的:)

import os, os.path

dirs = [f for f in os.listdir('.') if os.path.isdir(f)]