Verifying the existance of a file or folder using subprocess library in python
我可以很容易地使用OS库检查文件或文件夹的存在。以下两个链接描述了目录存在文件存在
我正试图使用子进程库来执行相同的操作
我已经试过几种方法了
1-status = subprocess.call(['test','-e',]),它总是返回1,不管我在路上经过什么。
2-使用GetStatusOutput,
/bin/sh: 1: : Permission denied
1 2 3
| status, result = subprocess.getstatusoutput([<path>])
print(status)
print(result) |
which is working fine because status variable returns 126 if the file/folder exist and 127 when the file/folder doesn't exist. Also the result variable contains message but the"result" variable contains the message : Permission denied
但第二个解决方案在我看来像是一个黑客。他们这样做更好吗?
- "/bin/sh:1::permission denied",在第二点错误地写了。
- 现代方法是使用pathlib。
- 不使用"~"。在我的Ubuntu平台上
- 我需要我的路径像"~/workspace/datasets"。
- 您可以使用Path.home()创建一条"~"路径。
- 曼尼什玛尔玛。对我来说,你的第一个例子很好。您是否知道,test在成功时返回零,在失败时返回非零?如果您需要Tilde扩展,则必须使用例如os.path.expanduser('~/workspace')。
- ~是一种壳体膨胀。如果您希望它在call()中工作,则需要添加shell=True。
- 格莱布杜。只有当命令是字符串而不是列表时,使用shell=True才有效,并且需要考虑到安全因素。
- @格利布德,它起作用了,对我来说这是一个愚蠢的错误,壳牌=真的起作用了。谢谢
- @格利布德,这对我有效,谢谢你带来了安全考虑。我自己读取用户名并单独生成路径以保持shell=false。这是正确的方法吗?
- @Ekhomodo当然有安全方面的考虑,但是shell=True的工作可以通过一个列表来完成。
- @另外,我注意到第一种方法不允许我区分文件和文件夹。
- 格莱布杜。不,它没有(无论如何,在Linux上)。
- @glibdud,在这种情况下,我可能会使用pathlib库。
- @不管怎样,我不知道你为什么决定这样做,而不仅仅是使用os。
- 格莱布杜。对我来说,call(['test', '-e', '~'], shell=True)返回1,而call('test -e ~', shell=True)返回0。
- 从python docs:子进程模块允许您生成新的进程,连接到它们的输入/输出/错误管道,并获取它们的返回代码。此模块打算替换几个较旧的模块和函数:os.system os.spawn*
- @Manishsharma,这意味着他们正试图替换那些特定的函数,而不是整个模块。
- @glibdud,是的,添加shell=true works
- 曼尼什玛尔玛。你为什么要用贝壳做这个?这似乎毫无意义,效率低下。
- 对我来说更有意义。我应该仔细阅读。谢谢你的澄清。
test命令是一个shell内置命令,在许多平台上,您不能作为独立的命令运行。
如果使用shell=True来使用shell来运行此命令,则应传入单个字符串,而不是令牌列表。
1
| status = subprocess.call("test -e '{}'".format(path), shell=True) |
如果path包含任何单引号,这将生成一个格式错误的命令;如果要完全正确和健壮,请尝试path.replace("'", r"\'"),或者使用现有的引用函数之一正确地转义所传入命令中的任何shell元字符。
subprocess库现在提供了一个函数run(),它比旧的遗留call()函数稍微简单一些;如果向后兼容性不重要,您可能应该切换到这个函数…或者,正如一些评论者已经恳求您的那样,当可移植的、轻量级的本机python解决方案可用时,不要对此任务使用subprocess。
- 对于它的价值,test -e只检查文件系统中是否存在具有给定名称的条目。也许您实际上正在查找test -f和test -d,它们分别检查它是指常规文件还是目录。
如评论部分所述
1
| status = subprocess.call(['test','-e',<path>]) |
如果使用"shell=true",则可以使用shell扩展
尽管使用os.path可能更有效。