如何在node.js中运行交互式shell命令? [英] How to run interactive shell command inside node.js?

查看:120
本文介绍了如何在node.js中运行交互式shell命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在node.js中运行一些交互式shell命令。让我们的交互式shell为 $ python

I have to run some interactive shell command inside node.js. Lets our interactive shell be $ 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();

此代码不输出任何内容(但是stdout应该 2 )。

This code does not output anything (but stdout should be 2).

但如果可以的话,会有另一个问题:如何让它互动?当我调用 pythonChildProcess.stdin.end(); 时,该过程结束!但我只是想结束stdin并写下一个stdin!

But if it would, there will be another problem: how to make it interactive? The process ends when I call pythonChildProcess.stdin.end();! But I just wanted to end stdin and write next stdin!

UPD:
如果我可以效仿按输入按钮 - 我将能够以交互方式写入该过程。但是在输入字符串的末尾添加 \ n 无济于事。

UPD: If I could emulate pressing of enter button - I would be able to interactively write to the process. But adding \n to the end of the input string does not help.

推荐答案

首先,阻止节点与其他交互式shell连接的一个原因是子应用程序必须保持其交互行为,即使 stdin 不存在看起来像一个终端。 python 这里知道它的 stdin 不是终端,所以它拒绝工作。这可以通过在python命令中添加 -i 标志来覆盖。

First and foremost, one of the things preventing node from interfacing with other interactive shells is that the child application must keep its "interactive" behavior, even when stdin doesn't look like a terminal. python here knew that its stdin wasn't a terminal, so it refused to work. This can be overridden by adding the -i flag to the python command.

其次,正如你在前面提到的那样更新时,您忘记将新行字符写入流,因此程序的行为就像用户没有按Enter键一样。
是的,这是正确的方法,但缺乏交互模式阻止您检索任何结果。

Second, as you well mentioned in the update, you forgot to write a new line character to the stream, so the program behaved as if the user didn't press Enter. Yes, this is the right way to go, but the lack of an interactive mode prevented you from retrieving any results.

您可以执行以下操作:将多个输入发送到交互式shell,同时仍然可以逐个检索每个结果。该代码将抵抗冗长的输出,累积它们直到在执行另一条指令之前接收到完整的行。也可以一次执行多个指令,如果它们不依赖于父进程的状态,则这可能是优选的。您可以尝试使用其他异步结构来实现目标。

Here's something you can do to send multiple inputs to the interactive shell, while still being able to retrieve each result one by one. This code will be resistant to lengthy outputs, accumulating them until a full line is received before performing another instruction. Multiple instructions can be performed at a time as well, which may be preferable if they don't depend on the parent process' state. Feel free to experiment with other asynchronous structures to fulfil your goal.

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');

这篇关于如何在node.js中运行交互式shell命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆