有没有办法确定nodejs子进程是否需要输入或只是发送反馈?

时间:2017-10-14 17:15:58

标签: javascript node.js child-process spawn

我有一点空闲时间所以我决定使用子进程重写JavaScript(NodeJS - ES6)中的所有bash脚本。一切顺利,直到我想自动化用户输入。

是的,您可以自动执行用户输入。但是有一个问题 - 您无法确定给定的data事件是反馈还是输入请求。至少我找不到办法。

所以基本上你可以这样做:

// new Spawn.
let spawn = require('child_process');
// new ufw process.
let ufw = spawn('ufw', ['enable']);

// Use defined input.
ufw.stdin.setEncoding('utf-8');
ufw.stdout.pipe(process.stdout);
ufw.stdin.write('y\n');

// Event Standard Out.
ufw.stdout.on('data', (data) => {
  console.log(data.toString('utf8'));
});

// Event Standard Error.
ufw.stderr.on('data', (err) => {
  // Logerror.
  console.log(err);
});

// When job is finished (with or without error) it ends up here.
ufw.on('close', (code) => {
  // Check if there were errors.
  if (code !== 0) console.log('Exited with code: ' + code.toString());
  // End input stream.
  ufw.stdin.end();
});

以上示例完全正常。但有两件事令我头疼:

  1. ufw.stdin.write('y\n');会等到需要它,如果我有多个输入会发生什么?例如'是','是',' no'。我是否必须写3行stdin.write()

  2. 我使用ufw.stdin.write('y\n');的位置有点令人困惑吗?在我的提示请求输入后我想我需要输入所以我决定更改我的stdin.write()可以在正确的时间运行的代码,这是正确的吗?然而,唯一的方法是检查“正确的”时间。时间是stdout.on('data', callback)事件。这使得思考有点困难,因为我需要知道提示是否需要用户输入...

  3. 这是我认为完全错误的代码:

    // new Spawn.
    let spawn = require('child_process');
    // new ufw process.
    let ufw = spawn('ufw', ['enable']);
    
    // Event Standard Out.
    ufw.stdout.on('data', (data) => {
      console.log(data.toString('utf8'));
    
      // Use defined input.
      ufw.stdin.setEncoding('utf-8');
      ufw.stdout.pipe(process.stdout);
      ufw.stdin.write('y\n');
    });
    
    // Event Standard Error.
    ufw.stderr.on('data', (err) => {
      // Logerror.
      console.log(err);
    });
    
    // When job is finished (with or without error) it ends up here.
    ufw.on('close', (code) => {
      // Check if there were errors.
      if (code !== 0) console.log('Exited with code: ' + code.toString());
      // End input stream.
      ufw.stdin.end();
    });
    

    我的主要误解是何时使用stdin进行用户输入(自动)以及将其放在我的代码中的位置,以便在适当的时候使用它,例如,如果我有多个输入,例如{ {1}}。

1 个答案:

答案 0 :(得分:0)

所以我想知道它是否可能而且似乎没有。我为节点发布了一个问题,最终关闭了:https://github.com/nodejs/node/issues/16214

I am asking for a way to determine if the current process is waiting for an input.
     

没有。我认为你对管道I / O有错误的期望   因为那根本不是它的运作方式。

     

谈论期望,请查看期望。可能有一个   如果环顾四周,可以使用node.js端口。

     

我将其关闭,因为它无法作为功能实现,并且   作为一个问题,nodejs / help是更合适的地方。

因此,如果任何人遇到与我相同的问题,您可以简单地将多行写入stdin并将其用作预定义值。请记住,如果功能更新中的任何输入被破坏或错误,最终会破坏流:

// new Spawn.
let spawn = require('child_process');
// new msqlsec process.
let msqlsec = spawn('mysql_secure_installation', ['']);
// Arguments as Array.
let inputArgs = ['password', 'n', 'y', 'y', 'y', 'y'];

// Set correct encodings for logging.
msqlsec.stdin.setEncoding('utf-8');
msqlsec.stdout.setEncoding('utf-8');
msqlsec.stderr.setEncoding('utf-8');

// Use defined input and write line for each of them.
for (let a = 0; a < inputArgs.length; a++) {
  msqlsec.stdin.write(inputArgs[a] + '\n');
}

// Event Standard Out.
msqlsec.stdout.on('data', (data) => {
  console.log(data.toString('utf8'));
});

// Event Standard Error.
msqlsec.stderr.on('data', (err) => {
  // Logerror.
  console.log(err);
});

// When job is finished (with or without error) it ends up here.
msqlsec.on('close', (code) => {
  // Check if there were errors.
  if (code !== 0) console.log('Exited with code: ' + code.toString());
  // close input to writeable stream.
  msqlsec.stdin.end();
});

为了完整起见,如果有人想手动填写用户输入,您可以像这样简单地启动给定的流程:

// new msqlsec process.
let msqlsec = spawn('mysql_secure_installation', [''], { stdio: 'inherit', shell: true });