【问题标题】:How to pass STDIN to node.js child process如何将 STDIN 传递给 node.js 子进程
【发布时间】:2016-06-07 17:17:36
【问题描述】:

我正在使用一个为节点包装 pandoc 的库。但我不知道如何将 STDIN 传递给子进程 `execFile...

var execFile = require('child_process').execFile;
var optipng = require('pandoc-bin').path;

// STDIN SHOULD GO HERE!
execFile(optipng, ['--from=markdown', '--to=html'], function (err, stdout, stderr) {
    console.log(err);
    console.log(stdout);
    console.log(stderr);
});

在 CLI 上看起来像这样:

echo "# Hello World" | pandoc -f markdown -t html

更新 1

试图让它与spawn一起工作:

var cp = require('child_process');
var optipng = require('pandoc-bin').path;
var child = cp.spawn(optipng, ['--from=markdown', '--to=html'], { stdio: [ 0, 'pipe', 'pipe' ] });

child.stdin.write('# HELLO');
// then what?

【问题讨论】:

    标签: node.js command-line-interface


    【解决方案1】:

    spawn() 一样,execFile() 也返回一个ChildProcess 实例,该实例具有stdin 可写流。

    作为使用write() 和侦听data 事件的替代方法,您可以创建readable streampush() 输入数据,然后将pipe() 设置为child.stdin

    var execFile = require('child_process').execFile;
    var stream   = require('stream');
    var optipng  = require('pandoc-bin').path;
    
    var child = execFile(optipng, ['--from=markdown', '--to=html'], function (err, stdout, stderr) {
        console.log(err);
        console.log(stdout);
        console.log(stderr);
    });
    
    var input = '# HELLO';
    
    var stdinStream = new stream.Readable();
    stdinStream.push(input);  // Add data to the internal queue for users of the stream to consume
    stdinStream.push(null);   // Signals the end of the stream (EOF)
    stdinStream.pipe(child.stdin);
    

    【讨论】:

      【解决方案2】:

      这是我如何让它工作的:

      var cp = require('child_process');
      var optipng = require('pandoc-bin').path; //This is a path to a command
      var child = cp.spawn(optipng, ['--from=markdown', '--to=html']); //the array is the arguments
      
      child.stdin.write('# HELLO'); //my command takes a markdown string...
      
      child.stdout.on('data', function (data) {
          console.log('stdout: ' + data);
      });
      child.stdin.end();
      

      【讨论】:

        【解决方案3】:

        字符串作为标准输入

        如果您使用同步方法(execFileSyncexecSyncspawnSync),您可以使用选项中的 input 键将 字符串作为标准输入。像这样:

        const child_process = require("child_process");
        const str = "some string";
        const result = child_process.spawnSync("somecommand", ["arg1", "arg2"], { input: str });
        

        【讨论】:

          【解决方案4】:

          根据这些docs 和以下摘录,我不确定是否可以将STDINchild_process.execFile() 一起使用,看起来它仅适用于child_process.spawn()

          child_process.execFile() 函数与 child_process.exec() 类似,只是它不生成 shell。相反,指定的可执行文件直接作为一个新进程生成,使其比 child_process.exec() 更高效。

          【讨论】:

          • @emersonthis 遵循我在答案中发布的文档链接,它显示了如何在代码 sn-p 中。
          • @emersonthis 用您的child_process.spawn() 代码更新您的问题,也许另一双眼睛会有所帮助?
          • 您是否尝试将选项添加到child_process.spawn() { stdio: [ 0, 'pipe', 'pipe' ] }
          • 是的。我用它更新了问题中的代码。不管我做什么,我都会得到TypeError: Cannot read property 'write' of null
          • 如果我能看到一个将 STDIN 传递给子进程的工作示例,我很确定我可以自己解决这个问题......要么是文档的链接,要么只是一个代码 sn-p .任何事情都会有帮助
          猜你喜欢
          • 2014-06-22
          • 1970-01-01
          • 1970-01-01
          • 2018-09-17
          • 1970-01-01
          • 1970-01-01
          • 2019-12-26
          • 2016-02-02
          • 2018-09-14
          相关资源
          最近更新 更多