Javascript node.js shell命令执行
我仍在努力掌握如何在node.js中运行linux或windows shell命令并捕获输出的细节;最终,我想做这样的事情Javascript node.js shell命令执行,javascript,node.js,shell,Javascript,Node.js,Shell,我仍在努力掌握如何在node.js中运行linux或windows shell命令并捕获输出的细节;最终,我想做这样的事情 //pseudocode output = run_command(cmd, args) 重要的一点是,输出必须可用于全局范围的变量(或对象)。我尝试了以下函数,但由于某种原因,我得到了未定义的打印到控制台 函数运行\u cmd(cmd、args、cb){ var spawn=require('child_process')。spawn var child=spawn(c
//pseudocode
output = run_command(cmd, args)
重要的一点是,输出
必须可用于全局范围的变量(或对象)。我尝试了以下函数,但由于某种原因,我得到了未定义的
打印到控制台
函数运行\u cmd(cmd、args、cb){
var spawn=require('child_process')。spawn
var child=spawn(cmd,args);
var me=这个;
child.stdout.on('data',函数(me,data){
cb(me,数据);
});
}
foo=newruncmd('dir',['/B'],函数(me,data){me.stdout=data;});
console.log(foo.stdout);//产生“未定义”在run\u cmd
函数中存在变量冲突:
var me = this;
child.stdout.on('data', function(me, data) {
// me is overriden by function argument
cb(me, data);
});
只需将其更改为:
var me = this;
child.stdout.on('data', function(data) {
// One argument only!
cb(me, data);
});
要查看错误,请始终添加以下内容:
child.stderr.on('data', function(data) {
console.log( data );
});
编辑您的代码失败,因为您试图运行目录
,而该目录不是作为单独的独立程序提供的。它是cmd
过程中的一个命令。如果您想使用文件系统,请使用本机require('fs')
或者(我不推荐)您可以创建一个批处理文件,然后运行该文件。请注意,操作系统默认情况下通过cmd
触发批处理文件这里有三个问题需要解决:
首先是异步使用stdout时需要同步行为。run\u cmd
函数中的所有调用都是异步的,因此它将生成子进程并立即返回,而不管是否从stdout读取了部分、全部或任何数据。因此,当你跑步时
console.log(foo.stdout);
此时,您将得到存储在foo.stdout中的任何内容,但无法保证会是什么,因为您的子进程可能仍在运行
第二个是stdout是一个,因此1)可以多次调用数据事件,2)为回调提供缓冲区,而不是字符串。易于补救;换衣服
foo = new run_cmd(
'netstat.exe', ['-an'], function (me, data){me.stdout=data;}
);
进入
因此,我们将缓冲区转换为字符串,并将该字符串附加到stdout变量
第三个是当您收到“end”事件时,您只能知道您已收到所有输出,这意味着我们需要另一个侦听器和回调:
function run_cmd(cmd, args, cb, end) {
// ...
child.stdout.on('end', end);
}
那么,您的最终结果是:
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\u cmd函数返回任何内容
function run_cmd(cmd, args, done) {
var spawn = require("child_process").spawn;
var child = spawn(cmd, args);
var result = { stdout: "" };
child.stdout.on("data", function (data) {
result.stdout += data;
});
child.stdout.on("end", function () {
done();
});
return result;
}
> foo = run_cmd("ls", ["-al"], function () { console.log("done!"); });
{ stdout: '' }
done!
> foo.stdout
'total 28520...'
很好用。:) 我也遇到了类似的问题,最后为此编写了一个节点扩展。您可以查看git存储库。它是开源的,免费的,还有所有的好东西
Excel是一个用C++编写的执行shell命令的节点扩展
一个接一个地将命令的输出输出到
实时的。存在可选的链接方式和未链接方式;意思
您可以选择在命令失败后停止脚本
(锁链),或者你可以继续,就好像什么都没发生一样
有关使用说明,请参阅。请随时提出请求或提交问题
我觉得值得一提。一个简化版的公认答案(第三点)对我来说很有用
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_cmd( "ls", ["-l"], function(text) { console.log (text) });
run_cmd( "hostname", [], function(text) { console.log (text) });
我用得更简洁一些:
var sys = require('sys')
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout) }
exec("ls -la", puts);
它工作得很好。:) 最简单的方法就是使用ShellJS库
$ npm install [-g] shelljs
执行示例:
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);
});
支持许多映射为NodeJS函数的常见shell命令,包括:
- 猫
- cd
- chmod
- cp
- dirs
- 回声
- exec
- 退出
- 查找
- grep
- ln
- ls
- mkdir
- mv
- popd
- pushd
- pwd
- rm
- sed
- 测试
- 哪个
@TonyO'Hagan的回答比较全面,但我想强调一下他的回答的同步版本:
var shell = require('shelljs');
var output = shell.exec('netstat -rn', {silent:true}).output;
console.log(output);
同步一行:
require('child_process').execSync("echo 'hi'", function puts(error, stdout, stderr) {
console.log(stdout)
});
最佳答案的预期版本:
runCmd: (cmd, args) => {
return new Promise((resolve, reject) => {
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 () { resolve(resp) })
})
}
使用:
runCmd('ls').then(ret => console.log(ret))
谢谢你的帮助。。。但是,即使在运行C:\Windows\System32\netstat.exe
时,这仍然不会产生结果。。。我的确切语法是foo=newrun_cmd('netstat.exe',['-an'],function(me,data){me.stdout=data;})代码>。。。我还尝试了完整的路径,但没有成功,因此我认为只要正确设置对象属性,就不需要返回返回
“无法保证会发生什么,因为您的子进程可能仍在运行”关闭…但可以保证不会在该时间点设置它,并且只有在最终调用回调时才会设置,正如您所指出的,这是一个非常好的答案,对一些非常重要的JS概念进行了很好的解释。美好的您将要执行this.stdout=“”
在run()
函数中,否则使用console.log(foo.sdtout)
将以undefined
作为前缀。返回值如何,当进程返回非零时,如何获取它?child.stdout.on('close',(errCode)=>{console.log(errCode)})
在最终解析中,您应该设置me.stdout=“”在cmd_exec()
中使用code>以防止将未定义的
连接到结果的开头。嘿,最终解析代码非常糟糕,如果执行netstat所需时间超过0.25秒怎么办?嗯。。。也许可以使用我奖励的答案中的一个,这个可能的副本工作得很好,并且不需要任何额外的节点模块。我喜欢sys.put()
在2中被弃用
runCmd: (cmd, args) => {
return new Promise((resolve, reject) => {
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 () { resolve(resp) })
})
}
runCmd('ls').then(ret => console.log(ret))