通过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输出之前,修改一下,再输出
问题了好多大神,都无法解决,哪位扫地僧给指点迷津呢?
你需要学习下 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解决方案!