问题描述
在使用tail
命令追踪日志文件时,我们可能会使用以下命令:
tail -f foo.log | grep bar
如果我们想要改变grep
的参数,我们必须使用Ctrl+C终止命令,然后更改参数,再重新启动命令。
我的问题是:是否有一种方法可以在不终止tail
或grep
命令的情况下动态更改我们要搜索的内容?如果可能,还想知道如何在使用less
而不是tail
时实现这一点。
解决方案
以下方案基于提供的回答和知识库,可能存在版本差异,请注意进行适当的调整。
使用Node.js实现动态更改grep参数
通过Node.js可以实现动态更改grep
参数,以避免终止命令。以下是一种实现方法,你可以通过一个名为dygrep
的工具来实现:
1. 在终端1中运行以下命令启动多个子进程并将其输出写入日志文件logfile.log
:
bash
many-child-procs > logfile.log
2. 在终端2中,使用tail
和grep
命令来过滤输出:
bash
tail -f logfile.log | grep <expression>
3. 使用dygrep
连接到TCP服务器,以控制过滤的表达式。
下面是基于Node.js实现的dygrep
工具的简要示例代码:
#!/usr/bin/env node
'use strict';
import * as readline from 'readline';
import * as net from 'net';
import chalk from 'chalk';
import { createParser } from "./json-parser";
import log from './logger';
let port = 4900;
const rl = readline.createInterface({
input: process.stdin.resume()
});
const regex = new Map<string, RegExp>();
rl.on('line', l => {
if (regex.size < 1) {
process.stdout.write(l + '\n');
return;
}
for (let [k, v] of regex) {
if (v.test(l)) {
process.stdout.write(chalk.magenta(' (filtered) ') + l + '\n');
break;
}
}
});
interface IncomingTCPMessage {
command: {
add: string,
remove: string,
list: boolean,
removeall: boolean
}
}
const server = net.createServer(s => {
const sendMessage = (m: any) => {
s.write(JSON.stringify({ message: m }) + `\n`);
};
s.pipe(createParser()).on('data', (d: IncomingTCPMessage) => {
if (!d.command) {
log.error('No "command" field was found:', d);
return ''
}
const c = d.command;
if (c.list) {
sendMessage({ regexes: Array.from(regex.keys()).map(k => ({ regex: regex.get(k), str: k })) });
log.info('Listing all regex for the client.');
return;
}
if (c.removeall) {
regex.clear();
sendMessage(`Cleared all regex.`);
log.info('Cleared all regex.');
return;
}
if (c.add) {
regex.set(c.add, new RegExp(c.add));
sendMessage(`Added regex: ${c.add}.`);
log.info('Added regex:', c.add);
return;
}
if (c.remove) {
regex.delete(c.remove);
sendMessage(`Deleted regex: ${c.remove}.`);
log.info('Removed regex:', c.remove);
return;
}
log.error('No matching field was found:', d);
log.info('Regex:', regex);
});
});
server.listen(port);
通过以上步骤,你可以实现动态更改grep
参数而不需要终止tail
命令。具体步骤涉及启动dygrep
工具以连接到TCP服务器,然后可以通过发送不同的命令来控制过滤的表达式。
请注意,此方案基于Node.js和dygrep
工具的实现。你可以在项目的GitHub仓库(https://github.com/ORESoftware/dygrep)中找到完整的代码和详细信息。
以上就是动态更改less/tail
的grep
参数的解决方案,希望能够帮助你实现这一功能。