繁体   English   中英

Nodejs:使用 EPIPE 写入 bash 进程的 stdin 崩溃

[英]Nodejs: write to stdin of bash process crashes with EPIPE

我的节点进程通过 HTTP 请求获取一些 PDF 文件,然后使用请求的onData事件将传入数据传递到正确配置的lpr ,通过child_process.exec产生。 我使用process.stdin.write(...)写入标准输入,然后在完成后使用process.stdin.end() 这使我可以立即打印这些文件。

现在我有一种情况,我不希望数据通过管道传输到lpr ,而是传输到一些 bash 脚本。 该脚本使用cat处理其stdin

myscript.sh < somefile.pdf按预期工作, cat somefile.pdf | myscript.sh也是如此 cat somefile.pdf | myscript.sh

但是,当我从节点生成/path/to/script.sh时(通过简单地将lpr替换为源中的脚本路径),进程退出

events.js:183 throw er; // Unhandled 'error' event ^ Error: write EPIPE at WriteWrap.afterWrite [as oncomplete] (net.js:868:14)

随后,整个节点进程崩溃,错误潜入所有try...catch块。 bash 脚本开头的日志显示,它甚至没有开始。

当我的目标不是 shell 脚本而是一些编译的可执行文件时,比如catecho ……一切都很好。 添加Epipebomb 模块不会改变任何东西。

我还尝试通过管道传输到process.exec("bash", ["-c cat | myscript.sh"]) ,但出现了相同的错误。

一个示例 bash 脚本,只是为了测试执行:

#!/usr/bin/env bash
date > logfile.txt
cat > /dev/null

编辑:我想我可能需要发出信号以某种方式保持标准输入流打开。 脚本的进程生成部分,将 promisification 和输出处理放在一边:

const process = require("child_process")    

// inputObservable being an rxjs Observable
execstuff(inputObervable) {
  const task = process.spawn("/path/to/script.sh");
  inputObservable.subscribe(
    chunk => task.stdin.write(chunk),
    error => console.error(error),
    finished => task.stdin.end()
  );
}

child_process.spawn 中有一个示例, 说明如何编写以下行ps ax | grep ssh ps ax | grep ssh作为 node.js 脚本,也许对你有帮助:

const { spawn } = require('child_process');
const ps = spawn('ps', ['ax']);
const grep = spawn('grep', ['ssh']);

ps.stdout.on('data', (data) => {
  grep.stdin.write(data);
});

ps.stderr.on('data', (data) => {
  console.log(`ps stderr: ${data}`);
});

第一印象是你在做同样的事情,问题可能出在块数据上,也许其中一个块是空的,它正在关闭流,你想通过运行 task.stdin.end( )。

您可以尝试的另一件事是使用NODE_DEBUG=stream node script.js运行 node.js 脚本NODE_DEBUG=stream node script.js将记录 node.js 内部的流,行为方式,也可能对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM