【问题标题】:Python Subprocess GrepPython 子进程 Grep
【发布时间】:2011-12-18 21:40:19
【问题描述】:
我正在尝试使用 subprocess 模块在 python 脚本中使用 grep 命令。
这是我所拥有的:
userid = 'foo12'
p = subprocess.Popen(['grep', "%s *.log"%userid], stdout=subprocess.PIPE)
它什么也不返回。
我不完全确定我做错了什么,所以有人可以解释一下。我正在使用的当前方法是通过添加 shell=true 使其输出正确的输出,但正如帮助页面指出的那样,它是不安全的。我需要帮助来完成这项工作,这样我的脚本才不会不安全。
【问题讨论】:
标签:
python
grep
subprocess
popen
【解决方案1】:
我认为您遇到了两个问题:
-
这个电话:
p = subprocess.Popen(['grep', "%s *.log"%userid]...
如果没有shell=True,将无法按预期工作,因为参数列表直接传递给os.execvp,这要求每个项目都是代表一个参数的单个字符串。您已将 两个单独的参数 压缩成一个字符串(换句话说,grep 将“foo12 *.log”解释为要搜索的 模式,而不是模式+文件列表)。
您可以通过以下方式解决此问题:
p = subprocess.Popen(['grep', userid, '*.log']...)
-
第二个问题是,同样没有shell=True,execvp 不知道您所说的*.log 是什么意思,并直接将其传递给grep,而无需通过shell 的通配符扩展机制。如果您不想使用shell=True,则可以改为:
import glob
args = ['grep', userid]
args.extend(glob.glob('*.log')
p = subprocess.Popen(args, ...)
【解决方案2】:
这里有两段经过测试的代码可供建模:
>>> print subprocess.check_output(['grep', 'python', 'api_talk.txt'])
Discuss python API patterns
Limitations of python
Introspection in python
>>> print subprocess.check_output('grep python *.txt', shell=True)
如果您希望 shell 为您进行通配符扩展,请使用后者。当 shell 为 True 时,请务必将整个命令放在单个字符串中,而不是单独的字段列表中。
【解决方案3】:
我假设您想在所有以 '.log' 结尾的文件中查找 'foo12',要使其仅与 subprocess 一起使用,您需要将代码更改为以下内容:
userid = 'foo12'
p = subprocess.Popen('grep %s *.log' % userid, stdout=subprocess.PIPE, shell=True)
shell=True 是通配符扩展所必需的,当设置该选项时,您需要提供字符串命令而不是列表。
另外,当您提供参数列表时,请确保每个参数都是列表中的一个单独条目,您的初始代码将等同于以下内容:
grep 'foo12 *.log'