【问题标题】:grep No such file or directory with envoy.rungrep envoy.run 没有这样的文件或目录
【发布时间】:2016-08-20 08:38:25
【问题描述】:

我尝试构建在我的日志中执行一些 grep 搜索并打印结果的脚本。 我尝试使用 Envoy,因为它比 subprocess 更容易,但是当我执行 grep 命令时,它会返回 no such file o directory 的错误。

目录结构很简单:

  • 。 # 脚本的根
  • test.py #脚本文件
  • web_logs/log/ # 包含要搜索的日志的目录

我的 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 模块,envoy 无法爆炸,所以我按原样使用子进程,并尝试更好地研究使用 glob 模块来改进 envoy。

我使用的新代码是:

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)

【问题讨论】:

  • 如果您将c=2 更改为不包含等号的术语,它是否有效?我不熟悉envoy,所以这绝对是在黑暗中拍摄。

标签: python grep python-envoy


【解决方案1】:

@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 命令运行将负责通配。

长答案

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

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

在 envoy 中,参数被解析为 envoy 代码中的 |(参见 def expand_args(command):)。然后使用 popen 的等价物来执行进程。 envoy 本质上就是 shell 对 | 标记所做的事情(在 | 上拆分,然后使用 popen)。

envoy 没有像 shell 那样解释 *,就像使用某种 glob 函数扩展它以匹配文件一样。巴什会。这就是我的答案。

一个有趣的练习是让你为 envoy 贡献代码 :-) 并让它做 globbing。

【讨论】:

  • 谢谢你们 baptistemm 和 @Ahmed,我选择了 Ahmed 是正确的,甚至另一个中心是我的代码的问题,我很快就使用子流程更新了我的答案,在我学习得更好之后glob 麻烦我尝试修改 envoy(即使最后一次更新是很久以前完成的......)
【解决方案2】:

为什么它在终端中起作用但在特使中不起作用与通配符有关 (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

当您在 envoy 中执行相同的操作时,会有所不同,它不会执行文件的 globing,然后它将传递给 grep 名为 ./web_logs/log/log_* 的文件,该文件不存在,这实际上已得到确认根据您在问题中粘贴的行。

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

ps:python 有一个glob module

【讨论】:

  • 关键是他的错误实际上是对 envoy.run 如何执行子进程的误解,而它显示为全局问题的事实只是一个副作用。
  • 虽然我知道原因,但由于我不认识特使,所以我没有提供解决方案。
  • 我为你 +1 ... 不知道谁给你 -1。
  • 没问题,别担心
  • 谢谢@baptistemm,我尝试阅读有关 glob 模块的更多信息,同时我解决了使用子进程而不是特使的问题。我用search = "grep 'cv="+str(value)+"' ./web_logs/log/log_*" proc = subprocess.check_output(search, shell=True) response = proc.split('\n')
猜你喜欢
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
  • 2017-10-28
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多