Bash命令在Python中无法正常运行

时间:2016-11-25 09:29:30

标签: python bash

我在目录中有以下文件

Co-sqp-C70.pdos_atm*5*C*_wfc*2*p*
Copilot

使用ls Co-sqp*过滤器,以便输出

Co-sqp-C70.pdos_atm*5*C*_wfc*2*p*

但是,在python脚本中,我使用了

cmd = ["ls", self.prefix+".pdos_atm*wfc*"]
output = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True).communicate()[0]
print(output)
return output.splitlines()

并且输出包含两个文件

Co-sqp-C70.pdos_atm*5*C*_wfc*2*p*
Copilot

我在python代码中做错了什么导致脚本没有正确过滤ls输出?

2 个答案:

答案 0 :(得分:0)

为了扩展IanAuld的评论,我想为您提供两种解决方案,解决您的问题而不依赖于调用子进程。使用子进程有点笨拙,并且为了查找文件,python提供了几个强大的pythonic选项。

我创建了一个名为files的文件夹,其中包含两个文件,其中包含您描述的名称和父文件夹中的python脚本:

find_files.py
files/
    Co-sqp-C70.pdos_atm*5*C*_wfc*2*p*
    Copilot

现在有几种方法可以做到这一点:

import glob
import os

# a glob solution
# you can use wildcards etc like in the command line
print(glob.glob("files/Co-sq*"))

# an os solution
# you can walk through all files and only print/ keep those that start with your desired string
for root, dirs, files in os.walk("files/"):
    for file in files:
        if file.startswith("Co-sq"):
            print(file)

我更希望使用glob解决方案来查找文件,因为它非常灵活且易于使用。顾名思义,glob允许您从命令行使用glob patterns

答案 1 :(得分:0)

您的命令不是bash ls。没有涉及扩展文件名模式self.prefix+".pdos_atm*wfc*"的shell,因此ls将其作为文字参数,就像您输入(在shell中)

一样
ls 'Co-sqp-C70.pdos_atm*wfc*'

您至少拥有以下选项:

  1. 调用shell以展开模式:

    cmd = [ "sh", "-c", "ls " + self.prefix + ".pdos_atm*wfc*"]
    

    等效地:

    cmd = "ls " + self.prefix + ".pdos_atm*wfc*"
    

    如果self.prefix不能保证是干净的,那么这是有风险的。

  2. 展开glob,并将结果传递给ls

    import glob
    cmd = ["ls"] + glob.glob(self.prefix+".pdos_atm*wfc*")
    

    您仍在使用ls,这不是为了提供可解析的输出。除了简单地将输出传递给用户(例如在日志文件中)之外,别做其他事情。

  3. 展开glob,并在python中处理结果:

    import glob
    for file in glob.glob(self.prefix+".pdos_atm*wfc*"):
        some_function(file)
    

    如果要以任何方式检查文件条目,则应执行此操作。