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
我认为你遇到了两个问题:
这个电话:
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)第二个问题是,再次没有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)以下是两个经过测试的代码片段,用于建模:
>>> 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为您进行通配符扩展,请使用后者.当shell为True时,请确保将整个命令放在单个字符串中,而不是单独的字段列表中.
我假设您想要在所有以'.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)