nodejs中如何知道子进程正在等待输入,并向其输入数据

比如npm login命令需要依次输入usernamepasswordemail

我启动一个子进程执行npm login我该如何知道子进程正在等待输入,并向其输入内容呢?

阅读 7.1k
2 个回答

是在控制台输入么,用readline,代码如下

// login.js
const readline = require('readline')

function createInput(msg) {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  })
  return new Promise(function(resolve, reject) {
    rl.question(`请输入${msg}: `, data => {
      rl.close()
      resolve(data)
    })
  })
}

Promise.resolve()
  .then(() => {
    return createInput('用户名').then(username => ({ username }))
  })
  .then(userInfo => {
    return createInput('密码').then(password => ({
      ...userInfo,
      password,
    }))
  })
  .then(userInfo => {
    return createInput('邮箱').then(email => ({
      ...userInfo,
      email,
    }))
  })
  .then(userInfo => {
    console.log(userInfo)
  })

补充

那可以用进程通讯,下面是简单的实现,你可以看看后面的参考文章,详细研究下node的进程间通讯
我是用node来实现的,如果发送端是别的语言的话,你需要找找相应语言是怎么实现进程通讯的

// login.js
const userInfo = {}
const codes = ['username', 'password', 'email']
let currIndex = 0

function get({ code, data }) {
  const currentCode = codes[currIndex]
  if (code === currentCode) {
    userInfo[code] = data
    const nextCode = codes[++currIndex]
    if (nextCode) {
      send(nextCode, `请给我 ${currentCode}`)
    } else {
      send('done', userInfo)
    }
  } else {
    send(currentCode, `请给我 ${currentCode}`)
  }
}
function send(code, message) {
  process.send({ code, message })
}
process.on('message', msg => {
  get(msg)
})

send(codes[currIndex], `请给我 ${codes[currIndex]}`)
// send-login.js
const { spawn } = require('child_process')
const child = spawn('node', ['login.js'], { stdio: [null, null, null, 'ipc'] })
const userInfo = {
  username: 'root',
  password: '123456',
  email: 'admin@root.com',
}
child.on('message', msg => {
  const { code } = msg

  if (code === 'done') {
    child.kill()
    console.log(msg.message)
  } else {
    child.send({ code, data: userInfo[code] })
  }
})

参考

新手上路,请多包涵

不知道你解决木有, 我也是今天刚解决的,共享一下。
参考大佬的文章 在Node.js中如何将数据以stdin的方式传递进由spawn产生的子进程?


const fs = require('fs');

const { spawn } = require('child_process');

var subProcess = spawn('cnpm.cmd', ['login'], { cmd: __dirname });
subProcess.on('error', function() {
    console.log('error');
    console.log(arguments);
});
subProcess.on('close', code => {
    if (code != 0) {
        console.log(`子进程退出码:${code}`);
    } else {
        console.log('登录成功');
    }
    process.stdin.end();
});
subProcess.stdin.on('end', () => {
    process.stdout.write('end');
});

subProcess.stdout.on('data', onData);
subProcess.stderr.on('data', onData);
function onData(data) {
    process.stdout.write('# ' + data);
    process.stdin.on('data', input => {
        input = input.toString().trim();
        subProcess.stdin.write(input + '\n');
    });
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏