node.js shell命令执行

Mik*_*ton 110 javascript shell node.js

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

//pseudocode
output = run_command(cmd, args)
Run Code Online (Sandbox Code Playgroud)

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

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" <------
Run Code Online (Sandbox Code Playgroud)

我无法理解代码在上面的位置......这个模型的一个非常简单的原型工作......

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" <----
Run Code Online (Sandbox Code Playgroud)

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

最终决议

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

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);
Run Code Online (Sandbox Code Playgroud)

Jam*_*ite 89

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

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

console.log(foo.stdout);
Run Code Online (Sandbox Code Playgroud)

你得到了目前存储在foo.stdout中的任何内容,并且不能保证会是什么,因为你的子进程可能仍在运行.

其次是stdout是一个可读的流,因此1)数据事件可以被多次调用,2)回调被赋予缓冲区,而不是字符串.易于补救; 只是改变

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

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

这样我们就可以将缓冲区转换为字符串并将该字符串附加到我们的stdout变量中.

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

function run_cmd(cmd, args, cb, end) {
    // ...
    child.stdout.on('end', end);
}
Run Code Online (Sandbox Code Playgroud)

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

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) }
);
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案,对一些非常重要的JS概念进行了很好的解释.太好了! (4认同)

cib*_*en1 78

接受的答案(第三点)的简化版本,对我有用.

function run_cmd(cmd, args, callBack ) {
    var spawn = require('child_process').spawn;
    var child = spawn(cmd, args);
    var resp = "";

    child.stdout.on('data', function (buffer) { resp += buffer.toString() });
    child.stdout.on('end', function() { callBack (resp) });
} // ()
Run Code Online (Sandbox Code Playgroud)

用法:

run_cmd( "ls", ["-l"], function(text) { console.log (text) });

run_cmd( "hostname", [], function(text) { console.log (text) });
Run Code Online (Sandbox Code Playgroud)

  • child.stdout.on('close',(errCode)=&gt; {console.log(errCode)}))` (2认同)

Mim*_*uni 48

我更简洁地使用了这个:

var sys = require('sys')
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout) }
exec("ls -la", puts);
Run Code Online (Sandbox Code Playgroud)

它完美地运作.:)

  • `sys.puts()`在2011年被弃用(使用Node.js v0.2.3).你应该使用`console.log()`代替. (9认同)

Ton*_*gan 42

最简单的方法就是使用ShellJS lib ...

$ npm install [-g] shelljs
Run Code Online (Sandbox Code Playgroud)

EXEC示例:

require('shelljs/global');

// Sync call to exec()
var version = exec('node --version', {silent:true}).output;

// Async call to exec()
exec('netstat.exe -an', function(status, output) {
  console.log('Exit status:', status);
  console.log('Program output:', output);
});
Run Code Online (Sandbox Code Playgroud)

ShellJs.org支持许多映射为NodeJS函数的常见shell命令,包括:

  • 光盘
  • CHMOD
  • CP
  • 迪尔斯
  • 回声
  • EXEC
  • 出口
  • grep的
  • LN
  • LS
  • MKDIR
  • MV
  • POPD
  • PUSHD
  • PWD
  • R M
  • SED
  • 测试
  • 哪一个