从子目录调用python脚本(使用子进程调用grep)会导致错误

从子目录调用python脚本(使用子进程调用grep)会导致错误,python,python-2.7,Python,Python 2.7,我通过python脚本调用grep,并将输出存储到列表中。我只想grep搜索具有特定文件扩展名的文件,即.c、.cpp和.h。我正在使用函数子进程。请检查\u output() (grep_pattern.py): 当我从同一个目录调用grep_pattern.py时,代码运行良好,即/grep_pattern,或者从它上面的任何目录调用grep_pattern.py,例如/scripts/python/grep_pattern.py,或者/python/grep_pattern.py。但是,如

我通过python脚本调用grep,并将输出存储到列表中。我只想
grep
搜索具有特定文件扩展名的文件,即.c、.cpp和.h。我正在使用函数
子进程。请检查\u output()

(grep_pattern.py):

当我从同一个目录调用grep_pattern.py时,代码运行良好,即
/grep_pattern
,或者从它上面的任何目录调用grep_pattern.py,例如
/scripts/python/grep_pattern.py
,或者
/python/grep_pattern.py
。但是,如果我从它下面的任何目录调用它,例如
。/grep\u pattern.py
。/../grep\u pattern.py

File "./grep_include.py", line 7, in <module>
  ls_output_str = subprocess.check_output(['grep', '-rl', '--include=*.{c,cpp,h}', 'pattern', '.'])
File "/<path>/lib/python2.7/subprocess.py", line 575, in check_output
  raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['grep', '-rl', '--include=*.{c,cpp,h}', 'pattern', '/projects/<path>/APACHE\n']' returned non-zero exit status 1
文件“/grep_include.py”,第7行,在
ls_output_str=subprocess.check_output(['grep','-rl','-include=*.{c,cpp,h}','pattern','.]))
文件“//lib/python2.7/subprocess.py”,第575行,在check_输出中
引发被调用的进程错误(retcode,cmd,output=output)
subprocess.CalledProcessError:命令'['grep','-rl','-include=*.{c,cpp,h}','pattern','/projects//APACHE\n']'返回非零退出状态1

奇怪的是,如果我删除了
”--include=*.{c,cpp,h}
选项,那么无论从何处调用代码,代码都可以工作

大括号不是模式匹配语法的一部分,
grep
--include
--exclude
参数不处理它们。相反,它们是shell的指令,用于创建它们所在的参数/单词的多个变体。你这里没有外壳,所以没有任何东西是遵守这些指示的

将其展开可能如下所示:

grep_str = subprocess.check_output(
    ['grep', '-rl',
     '--include=*.c',
     '--include=*.cpp',
     '--include=*.h',
     'pattern', '.'])
完成此操作后,
--include
模式实际上将能够匹配磁盘上存在的文件名,这样您的
grep
调用可能能够成功地找到该模式的匹配项,此时它可以返回成功的结果



顺便说一句——异常中给出的路径末尾的
\n
有点危险。除非您实际有一个以文字换行符结尾的目录名(这是可能的,但很少),否则请确保从
readline()
或类似文件接收时正确地剥离尾随换行符。

当您有一个shell时,
--include=*。{c,cpp,}
被拆分为三个单独的参数:
--include=*.c
,,
--include=*.cpp
--include=*.
。这里没有shell,所以您需要自己完成。而且,
rl
vs
-rl
看起来像是打字错误。事实上,这显然是一个打字错误,因为破折号在你的例外中。你的第一条评论就成功了,谢谢!关于使用strip()和拼写错误,您也是对的。它应该是-rl,而不是r1—无需在答案中编辑解决方案—单击复选框即可。(我们喜欢这种方法的部分原因是,如果有人稍后发布了更好的答案,他们的答案可能会被投赞成票,而我的答案可能会被投反对票——但编辑到问题中的答案具有“特殊地位”,因为不就问题本身投票就无法投票)。(…如果我只发表了评论,没有留下答案,但你想接受该评论作为答案,你可以自己添加一个带有评论信息的答案——标记“Community Wiki”是礼貌的,但不是必需的对于使用其他人内容的答案;但规则在这方面严格要求的只是归属)。
grep_str = subprocess.check_output(
    ['grep', '-rl',
     '--include=*.c',
     '--include=*.cpp',
     '--include=*.h',
     'pattern', '.'])