【问题标题】:NodeJS: Send message to persistent child process's stdin without human interaction?NodeJS:在没有人工交互的情况下向持久子进程的标准输入发送消息?
【发布时间】:2020-06-12 11:31:44
【问题描述】:

要求

我尝试将自定义消息发送到持久子进程的标准输入。子进程不是节点进程,而是任意程序。子进程使用 REPL 交互式提示来接受用户输入并将结果打印到标准输出,然后通过管道传回父进程。我需要能够不断向孩子发送消息并始终如一地获得结果。

我知道我们可以使用fork() 向基于 NodeJS 的子进程发送消息,但这不适用于非节点进程。

尝试 1:将父标准输入通过管道传输到子标准输入

我最初的尝试是允许用户从父进程的标准输入输入消息,并将其通过其子进程进行管道传输。这有效,但最终不是我想要的。

这里是父进程:hello_childstdin.js

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

const child = spawn('/usr/local/bin/python3', [join(__dirname, 'hello_childstdin.py')]);

process.stdin.pipe(child.stdin);

child.stdout.on('data', (data) => {
    console.log(`child stdout: \n${data}`);
});

child.stderr.on('data', (data) => {
    console.log(`child stderr: \n${data}`);
});

这里是子进程:hello_childstdin.py

while True:
    cmd = input('Enter command here (hello, bye, do it):')
    print('cmd: {}'.format(cmd))
    msg = cmd+': done\n' if cmd in ('hello', 'bye', 'do it') else 'undefined cmd: {}'.format(cmd)
    with open('/path/to/hello_childstdin.txt', 'a') as f:
        f.write(msg)
    print('msg: {}'.format(msg))

但是,我真正想要的是在没有人工干预的情况下直接向子进程的标准输入发送消息

我尝试了以下但失败了。

尝试 2:管道然后写入父标准输入。

父进程:hello_childstdin.js

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

const child = spawn('/usr/local/bin/python3', [join(__dirname, 'hello_childstdin.py')]);

process.stdin.pipe(child.stdin);

// Trying to write to parent process stdin
process.stdin.write('hello\n');

child.stdout.on('data', (data) => {
    console.log(`child stdout: \n${data}`);
});

child.stderr.on('data', (data) => {
    console.log(`child stderr: \n${data}`);
});

尝试 3:写入子标准输入。

父进程:hello_childstdin.js

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

const child = spawn('/usr/local/bin/python3', [join(__dirname, 'hello_childstdin.py')]);

process.stdin.pipe(child.stdin);

// Trying to write to parent process stdin
child.stdin.write('hello\n');

child.stdout.on('data', (data) => {
    console.log(`child stdout: \n${data}`);
});

child.stderr.on('data', (data) => {
    console.log(`child stderr: \n${data}`);
});

尝试 4

查看 child.stdin 的文档说明:

如果孩子正在等待读取其所有输入,它将不会继续 直到这个流被 end() 关闭。

然后我在我的父进程中尝试了以下操作。

// ... same as above ...

child.stdin.write('hello\n');
child.stdin.end();

// ... same as above ...

这会结束子进程,也不会写入消息。

与未分叉的子进程进行双向通信的正确方法是什么?

【问题讨论】:

    标签: javascript python node.js


    【解决方案1】:

    想通了:我可以将可读流推送给孩子。

    ...
    
    const stream = require('stream');
    
    ...
    
    var stdinStream = new stream.Readable();
    stdinStream.push('hello\n');  // Add data to the internal queue for users of the stream to consume
    stdinStream.pipe(child.stdin);
    
    

    感谢this answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 2018-09-07
      • 1970-01-01
      • 2015-06-29
      相关资源
      最近更新 更多