问了好多大神了,spawn调用子进程,实现拦截输入输出重定向,这个问题未能解决
发布于 4 年前 作者 Einsy 3353 次浏览 来自 问答

通过nodejs调用一个叫ginsh.exe的程序,在这里ginsh下载下载

ginsh.exe是一个命令行程序,希望通过nodejs程序可以实现输入输出重定向,经测试, 用下面的的代码可以实现

var fs = require(‘fs’); var child_process = require(‘child_process’); var subprocess = child_process.spawn(‘ginsh.exe’, { stdio: [ process.stdin, // Use parent’s stdin for child process.stdout, // Pipe child’s stdout to parent fs.openSync(‘err.out’, ‘w’) // Direct child’s stderr to a file ] });

下面的问题是,如何干预、拦截这个输入输出呢?就是输入之后,文本修改一下,再传入子进程ginsh.exe,ginsh.exe输出之前,修改一下,再输出

问题了好多大神,都无法解决,哪位扫地僧给指点迷津呢?

10 回复

你需要学习下 node stream 的知识

用pipe ,tty.js,都试了,都未能解决的 @atian25

例如输入x=1 后面补个分号送入 ginsh.exe, 当然最终不止是加分号,这里举个例子,

你的问题好像说的不是太明白,你这个需求谁来触发? 如果用户通过request触发了这个,那你自然是能知道用户传过来的输入参数,你再把参数调整后传入ginsh.exe,然后再把它的输出通过responese返回给用户(包括err输出) 不知道是不是我理解的问题,刚睡醒,还有点迷迷糊糊的就看见你的问题了。

您下载那个包试试,运行下node test试试. test.js也就是上面贴的代码。 如果能实现异步发送数据进入子进程最好; 或者http ajax请求得到一文本,或者setTimeout后请求也可以; 现在第一个问题:重定向拦截,修改输入输出数据,修改都没解决; 至于异步发送数据到子进程又是另外一个问题了。这也是需要解决的第二个问题。 第二个问题:异步输入,或者说通过API调用发送数据到子进程,这是另外一种调用方式。也是需要解决的。

stream 版

const { spawn } = require('child_process');
const { join } = require('path');
const concat = require('concat-stream');

const concatStream = concat((res)=>{
  console.log(res.toString());
});

const task = spawn(join(__dirname, 'ginac\\bin\\ginsh.exe'), [], {
  stdio: 'pipe'
});
task.stdout.pipe(concatStream);
task.stdin.write('x=1+1;exit;')
task.stdin.end();

伪终端版:

const pty = require('node-pty');
const { join } = require('path');
const task = pty.spawn(join(__dirname, 'ginac\\bin\\ginsh.exe'), [], {})

task.on('data', (data) => {
  console.log(`输出:${data}`)
});

const sequences = [
  "x=1;",
  "y=1;",
  "z=x+y;"
];

const step = () => {
  const command = sequences.shift();
  if (command) {
    process.stdout.write(`输入:${command}\n`)
    task.write(`${command}\n`);
    setTimeout(step, 1000);
  } else {
    // process.exit();
  }
}

setTimeout(step,1000);

@wyvernnot 能否不执行task.stdin.end(); 执行end之后会断开进程,因为要支持多次输入输出交互。 采用concat-stream之后,也无法支持在当前runtime天多次输入输出交互的

@Einsy 哎,群里发给你的很清楚的说明了工作原理。用父进程接受输入,然后把接受到的输入write子进程中

这个就能达到重定向,但是无法劫持修改的 var fs = require(‘fs’); var child_process = require(‘child_process’);

var subprocess = child_process.spawn(‘ginsh.exe’, { stdio: [ process.stdin, // Use parent’s stdin for child process.stdout, // Pipe child’s stdout to parent fs.openSync(‘err.out’, ‘w’) // Direct child’s stderr to a file ] });

感谢 福州 Yeah网友,感谢王龙天 @wyvernnot 一个提供C++解决方案 一个提供nodejs解决方案!

回到顶部