我尝试在我的日志中构建执行grep搜索的脚本并打印结果。 我尝试使用Envoy,因为它比子进程更容易,但是当我执行grep命令时,它给了我一个错误,没有这样的文件o目录。
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)
答案 0 :(得分:2)
@baptistemm实际上是正确的,因为你没有在你的过程中运行bash,所以globbing不起作用。
然而,发生的事情要深一些。
当您运行子流程时,可以通过多个系统服务之一(系统调用)来完成。
以下是正确的方法:
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