如何在node.js中运行交互式shell命令?
我必须在node.js中运行一些交互式shell命令。 让我们的交互式shell是$ python
:
var cp = require('child_process'); var pythonChildProcess = cp.spawn('python'); pythonChildProcess.stdout.on("data", function(data) { console.log('data successfully written!', data); // never outputs anything }); pythonChildProcess.stdin.write('1 + 1'); pythonChildProcess.stdin.end();
此代码不输出任何内容(但标准输出应为2
)。
但是如果会的话,还会有另外一个问题:如何让它互动? 当我调用pythonChildProcess.stdin.end();
! 但我只是想结束stdin并写下一个stdin!
UPD:如果我可以模仿按下enter
button – 我将能够交互式写入进程。 但是将\n
添加到inputstring的末尾并不会帮助。
首先,阻止节点与其他交互式shell交互的事情之一是,子应用程序必须保持其“交互式”行为,即使stdin
看起来不像terminal。 python
在这里知道它的stdin
不是terminal,所以它拒绝工作。 这可以通过向python命令添加-i
标志来覆盖。
其次,正如你在更新中提到的,你忘了写一个新的行字符到stream中,所以程序的行为就好像用户没有按下Enter键一样。 是的,这是正确的路要走,但缺乏交互模式阻止您检索任何结果。
以下是可以将多个input发送到交互式shell的操作,同时仍然可以逐一检索每个结果。 这个代码将抵抗长时间的输出,在执行另一条指令之前累积它们直到收到全行。 一次可以执行多个指令,如果它们不依赖于父进程的状态,这可能是更好的。 随意尝试其他asynchronous结构来实现您的目标。
var cp = require('child_process'); var childProcess = cp.spawn('python', ['-i']); childProcess.stdout.setEncoding('utf8') var k = 0; var data_line = ''; childProcess.stdout.on("data", function(data) { data_line += data; if (data_line[data_line.length-1] == '\n') { // we've got new data (assuming each individual output ends with '\n') var res = parseFloat(data_line); data_line = ''; // reset the line of data console.log('Result #', k, ': ', res); k++; // do something else now if (k < 5) { // double the previous result childProcess.stdin.write('2 * + ' + res + '\n'); } else { // that's enough childProcess.stdin.end(); } } }); childProcess.stdin.write('1 + 0\n');
@E_net4的答案的tl; dr版本,对于那些只懂阅读代码的人来说。 有关详细的解释,请阅读他的答案。 他描述得很好。
var spawn = require('child_process').spawn var p = spawn('node',['-i']); p.stdout.on('data',function (data) { console.log(data.toString()) }); p.stdin.write('1 + 0\n');
输出:
> 1