Python Subprocess Grep

Jas*_*Zhu 12 python grep subprocess popen

我试图使用子进程模块在python脚本中使用grep命令.

这就是我所拥有的:

userid = 'foo12'
p = subprocess.Popen(['grep', "%s *.log"%userid], stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

它什么也没有回报.我不完全确定我做错了什么,所以有人可以解释一下.我正在使用的当前方法是通过添加shell = true来使其输出正确的输出,但是帮助页面指出它是不安全的.我需要帮助尝试使这项工作,以便我的脚本不安全.

bjl*_*aub 11

我认为你遇到了两个问题:

  1. 这个电话:

    p = subprocess.Popen(['grep', "%s *.log"%userid]...
    
    Run Code Online (Sandbox Code Playgroud)

    如果不shell=True直接传递参数列表,则不会按预期工作os.execvp,这需要每个项目都是表示参数的单个字符串.你已经将两个单独的参数拼凑成一个单独的字符串(换句话说,grep将" foo12 *.log" 解释为要搜索的模式,而不是模式+文件列表).

    您可以通过说:

    p = subprocess.Popen(['grep', userid, '*.log']...)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 第二个问题是,再次没有shell=True,execvp不知道你的意思*.log并将其直接传递给grep,而不通过shell的通配符扩展机制.如果您不想使用shell=True,您可以改为:

    import glob
    args = ['grep', userid]
    args.extend(glob.glob('*.log')
    p = subprocess.Popen(args, ...)
    
    Run Code Online (Sandbox Code Playgroud)


Ray*_*ger 9

以下是两个经过测试的代码片段,用于建模:

>>> 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)
Run Code Online (Sandbox Code Playgroud)

如果您希望shell为您进行通配符扩展,请使用后者.当shellTrue时,请确保将整个命令放在单个字符串中,而不是单独的字段列表中.


And*_*ark 5

我假设您想要在所有以'.log'结尾的文件中使用'foo12',为了使其能够正常工作,subprocess您需要将代码更改为以下内容:

userid = 'foo12'
p = subprocess.Popen('grep %s *.log' % userid, stdout=subprocess.PIPE, shell=True)
Run Code Online (Sandbox Code Playgroud)

shell=True 对于通配符扩展是必需的,并且当设置该选项时,您需要提供字符串命令而不是列表.

此外,请确保在提供参数列表时,每个参数都是列表中的单独条目,您的初始代码将等同于以下内容:

grep 'foo12 *.log'
Run Code Online (Sandbox Code Playgroud)