node.js shell命令执行 [英] node.js shell command execution

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

问题描述

我仍然试图掌握如何运行linux或windows shell命令以及在node.js中捕获输出的更好点;最终,我想做这样的事情...

I am still trying to grasp the finer points of how I can run a linux or windows shell command and capture output within node.js; ultimately, I want to do something like this...

//pseudocode
output = run_command(cmd, args)

重要的是输出必须可用于全局范围的变量(或对象)。我尝试了以下功能,但出于某种原因,我将 undefined 打印到控制台...

The important piece is that output must be available to a globally scoped variable (or object). I tried the following function, but for some reason, I get undefined printed to the console...

function run_cmd(cmd, args, cb) {
  var spawn = require('child_process').spawn
  var child = spawn(cmd, args);
  var me = this;
  child.stdout.on('data', function(me, data) {
    cb(me, data);
  });
}
foo = new run_cmd('dir', ['/B'], function (me, data){me.stdout=data;});
console.log(foo.stdout);  // yields "undefined" <------

我无法理解哪里代码突破上面...该模型的一个非常简单的原型工作...

I'm having trouble understanding where the code breaks above... a very simple prototype of that model works...

function try_this(cmd, cb) {
  var me = this;
  cb(me, cmd)
}
bar = new try_this('guacamole', function (me, cmd){me.output=cmd;})
console.log(bar.output); // yields "guacamole" <----

有人可以帮我理解为什么 try_this()有效, run_cmd()不行? FWIW,我需要使用 child_process.spawn ,因为 child_process.exec 有200KB的缓冲限制。

Can someone help me understand why try_this() works, and run_cmd() does not? FWIW, I need to use child_process.spawn, because child_process.exec has a 200KB buffer limit.

我接受James White的回答,但这是对我有用的确切代码...

I'm accepting James White's answer, but this is the exact code that worked for me...

function cmd_exec(cmd, args, cb_stdout, cb_end) {
  var spawn = require('child_process').spawn,
    child = spawn(cmd, args),
    me = this;
  me.exit = 0;  // Send a cb to set 1 when cmd exits
  me.stdout = "";
  child.stdout.on('data', function (data) { cb_stdout(me, data) });
  child.stdout.on('end', function () { cb_end(me) });
}
foo = new cmd_exec('netstat', ['-rn'], 
  function (me, data) {me.stdout += data.toString();},
  function (me) {me.exit = 1;}
);
function log_console() {
  console.log(foo.stdout);
}
setTimeout(
  // wait 0.25 seconds and print the output
  log_console,
250);


推荐答案

这里有三个问题需要修复:

There are three issues here that need to be fixed:

首先是您在异步使用stdout时期望同步行为。 run_cmd 函数中的所有调用都是异步的,因此它将生成子进程并立即返回,无论是否已读取部分,全部或全部数据stdout。因此,当你运行

First is that you are expecting synchronous behavior while using stdout asynchronously. All of the calls in your run_cmd function are asynchronous, so it will spawn the child process and return immediately regardless of whether some, all, or none of the data has been read off of stdout. As such, when you run

console.log(foo.stdout);

你现在收到foo.stdout中存储的任何内容,并且不能保证那是什么将是因为您的子进程可能仍在运行。

you get whatever happens to be stored in foo.stdout at the moment, and there's no guarantee what that will be because your child process might still be running.

第二是stdout是可读流,因此1)数据事件可以被多次调用,2)回调被赋予缓冲区,而不是字符串。易于补救;只需更改

Second is that stdout is a readable stream, so 1) the data event can be called multiple times, and 2) the callback is given a buffer, not a string. Easy to remedy; just change

foo = new run_cmd(
    'netstat.exe', ['-an'], function (me, data){me.stdout=data;}
);

进入

foo = new run_cmd(
    'netstat.exe', ['-an'], function (me, buffer){me.stdout+=buffer.toString();}
);

因此我们将缓冲区转换为字符串并将该字符串附加到我们的stdout变量。

so that we convert our buffer into a string and append that string to our stdout variable.

第三是你只能知道在收到'end'事件时你已收到所有输出,这意味着我们需要另一个监听器和回调:

Third is that you can only know you've received all output when you get the 'end' event, which means we need another listener and callback:

function run_cmd(cmd, args, cb, end) {
    // ...
    child.stdout.on('end', end);
}

所以,你的最终结果如下:

So, your final result is this:

function run_cmd(cmd, args, cb, end) {
    var spawn = require('child_process').spawn,
        child = spawn(cmd, args),
        me = this;
    child.stdout.on('data', function (buffer) { cb(me, buffer) });
    child.stdout.on('end', end);
}

// Run C:\Windows\System32\netstat.exe -an
var foo = new run_cmd(
    'netstat.exe', ['-an'],
    function (me, buffer) { me.stdout += buffer.toString() },
    function () { console.log(foo.stdout) }
);

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

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