【问题标题】:Python - execute find with multiple conditions using PopenPython - 使用 Popen 执行具有多个条件的查找
【发布时间】:2013-03-18 04:55:59
【问题描述】:

我想在多个条件下执行find,例如:查找 foo 排除隐藏文件:

find . -type f \( -iname '*foo*' ! -name '.*' \)

Python 代码:

import subprocess

cmd = ["find", ".", "-type", "f", "(", "-iname", "*foo*", "!", "-name", ".*", ")"]
sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print sp.communicate()[0].split()

有人可以解释我缺少什么吗?谢谢!

【问题讨论】:

  • 顺便说一句,使用os.path.walk,您可以轻松实现纯 Pythonish walk,无需外部子处理
  • 我遇到了同样的问题,即使没有排除隐藏文件。
  • 你得到什么错误?您应该改用-print0.split('\0')

标签: python subprocess popen


【解决方案1】:

我也遇到了这个问题,我相信你现在已经弄清楚了,但我想我会权衡一下,以防其他人遇到同样的问题。来看看,这是因为当你使用 Popen 时 Python 实际在做什么(当使用 shell=True 时,python 基本上只是使用 /bin/sh -c 来传递你的命令(Python's subprocess.Popen() results differ from command line?)。shell 是默认情况下为 False,因此如果您省略此选项或将其设置为 False,则将使用 'executable' 中指定的任何内容。文档在此处详细介绍:https://docs.python.org/2/library/subprocess.html#subprocess.Popen

按照这些思路应该可以工作

import subprocess
cmd = 'find . -type f -iname "*foo*" ! -name ".*"'
sp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print sp.communicate()[0].split()

【讨论】:

  • Popen 不会运行/bin/sh,除非您使用shell=True 要求它
  • 我已经根据您的评论澄清了这一点。这仍然有效。
  • 问题中的代码按原样工作。你不需要shell=True
  • 奇怪——如果我省略 shell=True,我的代码就会崩溃。 dir_list = subprocess.Popen(command, stdout=subprocess.PIPE) 然后调用等待退出代码 out, err = dir_list.communicate() 并返回。 编辑刚刚发现我们的服务器使用的是 2.6.6——如果更新到 2.7 可以解决我的问题,我会编辑它。
  • 您应该使用列表参数,例如shlex.split(cmd)
【解决方案2】:

在 python 3.7 subprocess.run() 中,您可以将空格上的 cmd 拆分成一个列表,字符串就可以了。

尽管subrocess.run(),但文档中没有任何内容。

我无法将命令扩展为列表以工作,而字符串工作正常。

cmd = "find . -type f -iname \*foo\* ! -name .\\*"
print(cmd)
ret = subprocess.run(cmd, shell=True, capture_output=True)
print(ret)

测试:

$ find . -type f -iname \*foo\* ! -name .\*
./foobar.txt
./barfoo.txt

$ ./findfoo.py
find . -type f -iname \*foo\* ! -name .\*
CompletedProcess(args='find . -type f -iname \\*foo\\* ! -name .\\*',
 returncode=0, stdout=b'./foobar.txt\n./barfoo.txt\n', stderr=b'')

【讨论】:

    【解决方案3】:

    至少,需要转义那里的*。

    第二次通过反斜杠转义 ( 和 )(将 "\\(" 和 "\\)" 传递给 shell)

    cmd = ["find", ".", "-type", "f", "\\(", "-iname", "\\*foo\\*", "!", "-name", ".\\*", "\\)"]
    

    甚至干脆去掉那些 ( 和 ) -

    cmd = ["find", ".", "-type", "f", "-iname", "\\*foo\\*", "!", "-name", ".\\*"]
    

    应该没问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 2017-07-25
      相关资源
      最近更新 更多