Node.js 节点';s childProcess.spawn-管道不';行不通
我想实时读取和解析(使用Node.js 节点';s childProcess.spawn-管道不';行不通,node.js,shell,nginx,pipe,child-process,Node.js,Shell,Nginx,Pipe,Child Process,我想实时读取和解析(使用awk)我的nginx日志。因此,我编写了这个shell命令来实现这一点,如果我在shell中运行它,它就会工作: tail -f -n +1 /var/log/nginx/access.log | awk '{print $1, $7, $9}' 但我无法在节点中运行它。我编写这段代码是为了运行我的命令(取自node.js文档中的示例),但它没有显示任何内容: const tail = childProcess.spawn('tail',['-f', '-n', '+
awk
)我的nginx日志。因此,我编写了这个shell命令来实现这一点,如果我在shell中运行它,它就会工作:
tail -f -n +1 /var/log/nginx/access.log | awk '{print $1, $7, $9}'
但我无法在节点中运行它。我编写这段代码是为了运行我的命令(取自node.js文档中的示例),但它没有显示任何内容:
const tail = childProcess.spawn('tail',['-f', '-n', '+1', nginxAccessLog]);
const awk = childProcess.spawn('awk', ['{print $1, $7, $9}'], { stdio: [tail.stdout, 'pipe', 'pipe'] })
tail.stdout.on('data', (data) => {
console.log('tail output', data.toString());
})
awk.stdout.on('data', (data) => {
console.log('awk output', data.toString());
})
tail.on('error', () => 'tail error')
awk.on('error', () => 'awk error')
tail.on('close', () => console.log('tail end', result));
awk.on('close', () => console.log('awk end', result));
我可以看到我的进程已经生成(它们在htop
输出中),但我没有输出。
如何修复此问题?不太清楚为什么将
tail.stdout
传递到Awk进程不起作用(我猜在创建Awk进程时,tail.stdout
可能尚未附加有效的文件描述符),但这确实起到了以下作用:
const tail = childProcess.spawn('tail',['-f', '-n', '+1', nginxAccessLog]);
const awk = childProcess.spawn('awk', ['{print $1, $7, $9}'], { stdio: [ 'pipe', process.stdout ] });
tail.stdout.pipe(awk.stdin);
请注意,因为您使用的是tail-f
,所以管道将继续运行
编辑:如果您不打算只记录输出,而是处理输出,那么情况会变得更加复杂,因为Awk会缓冲其输出(我相信高达4K)
您需要在Awk中强制刷新,可以使用fflush(“”
或system(“”
)触发刷新。因此,代码变成:
const tail = childProcess.spawn('tail',['-f', '-n', '+1', nginxAccessLog]);
const awk = childProcess.spawn('awk', [ '{print $1, $7, $9; fflush(""); }']);
tail.stdout.pipe(awk.stdin);
awk.stdout.on('data', data => {
console.log('awk output:', data.toString());
});
这似乎给输出添加了空行,但我想这些空行是可以过滤掉的。对我来说,它会与
awk.stdout.on('data',(data)=>{TypeError:Cannot read property'on'of null
。如果我注释掉awk.stdout.on('data',…)
callback,它将在终端上显示输出。但是我如何才能在callback中获得awk
输出,就像我的问题一样?啊,我误解了,我假设您只想做控制台。记录输出。我将编辑我的答案。