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

查看:32
本文介绍了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)

重要的是 output 必须可用于全局范围的变量(或对象).我尝试了以下功能,但由于某种原因,我将 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 函数中的所有调用都是异步的,因此它会生成子进程并立即返回,无论是否从标准输出中读取了部分、全部或全部数据.因此,当你运行

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.

第二是标准输出是一个可读流,所以 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.

第三是只有当您收到结束"事件时,您才能知道您已收到所有输出,这意味着我们需要另一个侦听器和回调:

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:WindowsSystem32
etstat.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天全站免登陆