grep没有这样的文件或目录与envoy.run

时间:2016-08-20 08:38:26

标签: python grep python-envoy

我尝试在我的日志中构建执行grep搜索的脚本并打印结果。 我尝试使用Envoy,因为它比子进程更容易,但是当我执行grep命令时,它给了我一个错误,没有这样的文件o目录。

dir结构很简单:

  • 。 #roa of script
  • test.py#script file
  • web_logs / log / #dir,其中包含要搜索的日志

我的test.py很简单:

import envoy

def test(value):

   search = "grep 'cv="+str(value)+"' ./web_logs/log/log_*"
   print(search) #check of the search string
   r = envoy.run(search)
   print(r.status_code, r.std_out, r.std_err)#check of the command
   response = r.std_out

if __name__ == "__main__":
   test(2)

输出结果为:

grep 'cv=2' ./web_logs/log/log_*
(2, '', 'grep: ./web_logs/log/log_*: No such file or directory\n')

如果我运行相同的命令:

grep 'cv=2' ./web_logs/log/log_*

我可以在日志文件中找到字符串“cv = 2”的出现。

错误在哪里?

在答案后更新 问题在于使用*特使不使用glob模块就不会爆炸,所以我按原样使用子进程,并尝试更好地研究使用glob模块来改进特使。

我使用的新代码是:

import subprocess

def test(value):

   search = "grep 'cv="+str(value)+"' ./web_logs/log/log_*"
   print(search) #check of the search string
   proc = subprocess.check_output(search, shell=True)
   print proc.split('\n')

if __name__ == "__main__":
   test(2)

2 个答案:

答案 0 :(得分:2)

@baptistemm实际上是正确的,因为你没有在你的过程中运行bash,所以globbing不起作用。

然而,发生的事情要深一些。

当您运行子流程时,可以通过多个系统服务之一(系统调用)来完成。

简答(TLDR;)

以下是正确的方法:

import envoy

def test(value):

   search = "/bin/sh -c \"grep 'cv="+str(value)+"' ./web_logs/log/log_*\""
   print(search) #check of the search string
   r = envoy.run(search)
   print(r.status_code, r.std_out, r.std_err)#check of the command
   response = r.std_out

if __name__ == "__main__":
   test(2)

将命令作为shell命令运行将处理globbing。

长答案

每当执行子进程时,它最终会被转换为execve系统调用(或等效的)。

C库中有诸如system(3)popen(3)之类的帮助函数,它们包围execve(2)以提供更简单的执行进程的方法。 system启动一个shell并将其参数原样传递给shell的-c选项。 popen做了额外的魔术,有点像特使在python中所做的那样。

在特使中,参数在特使代码中被解析为|(参见def expand_args(command):)。然后使用等效的popen来执行进程。 envoy基本上是shell对|标记执行的操作(在|之间拆分,然后使用popen)。

什么特使没有做的就像shell一样解释*,就像扩展它以使用某种glob函数来匹配文件一样。巴什呢。因此,我的答案。

一个有趣的练习是让你为代理贡献代码:-)并让它做成全局。

答案 1 :(得分:1)

为什么它在终端中工作但在特使中不起作用与globbing(bash example)有关。

在终端中运行时

grep 'cv=2' ./web_logs/log/log_*

bash将解析命令行并将每个匹配的文件替换为星号。因此,如果您有./web_logs/log/log_1 ./web_logs/log/log_2./web_logs/log/log_foo,那么您的命令实际上就是

grep 'cv=2' ./web_logs/log/log_1 ./web_logs/log/log_2 ./web_logs/log/log_foo

当你在特使执行相同的事情时,那就不同了,它不会执行文件的整理,然后它会传递给grep一个名为./web_logs/log/log_*的文件,这个文件不存在,这是实际上是通过你在问题中粘贴的行确认的。

print r.std_err
'grep: ./web_logs/log/log_*: No such file or directory\n'

ps:python有glob module