[javascript] node.js 셸 명령 실행
Linux 또는 Windows 셸 명령을 실행하고 node.js 내에서 출력을 캡처 할 수있는 방법에 대한 세부 사항을 여전히 파악하려고합니다. 궁극적으로 이렇게하고 싶습니다 …
//pseudocode
output = run_command(cmd, args)
중요한 부분은 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" <------
위의 코드가 어디에서 깨지는 지 이해하는 데 어려움이 있습니다 … 그 모델의 매우 간단한 프로토 타입이 작동합니다 …
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, 200KB 버퍼 제한이 child_process.spawn
있기 child_process.exec
때문에을 사용해야 합니다.
최종 해결책
나는 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);
답변
여기에서 수정해야 할 세 가지 문제가 있습니다.
첫 번째 는 stdout을 비동기 적으로 사용하는 동안 동기 동작을 기대한다는 것입니다. run_cmd
함수 의 모든 호출 은 비동기식이므로 자식 프로세스를 생성하고 데이터의 일부, 전체 또는 데이터가 stdout에서 읽혀지지 않았는지 여부에 관계없이 즉시 반환됩니다. 따라서 실행하면
console.log(foo.stdout);
현재 foo.stdout에 저장되는 것은 무엇이든 얻을 수 있으며 자식 프로세스가 여전히 실행 중일 수 있기 때문에 그것이 무엇인지 보장 할 수 없습니다.
두 번째 는 stdout이 읽을 수있는 스트림 이므로 1) 데이터 이벤트를 여러 번 호출 할 수 있고 2) 콜백에 문자열이 아닌 버퍼가 제공된다는 것입니다. 치료하기 쉽습니다. 그냥 변경
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 변수에 추가합니다.
세 번째 는 ‘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) }
);
답변
받아 들여지는 대답의 단순화 된 버전 (세 번째 점)은 저에게 효과적이었습니다.
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 lib를 사용하는 것입니다.
$ npm install [-g] shelljs
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);
});
ShellJs.org 는 다음을 포함하여 NodeJS 함수로 매핑 된 많은 공통 셸 명령을 지원합니다.
- 고양이
- CD
- chmod
- cp
- Dirs
- 에코
- 임원
- 출구
- 찾기
- grep
- ln
- ls
- mkdir
- mv
- 팝
- 푸시
- 암호
- rm
- sed
- 테스트
- 어느
답변
비슷한 문제가 있었고 결국 이에 대한 노드 확장을 작성했습니다. git 저장소를 확인할 수 있습니다. 그것은 오픈 소스이며 무료이며 모든 좋은 것들입니다!
https://github.com/aponxi/npm-execxi
ExecXI는 C ++로 작성된 노드 확장으로, 쉘 명령을 하나씩 실행하여 명령의 출력을 실시간으로 콘솔에 출력합니다. 선택적 연결 및 연결 해제 방법이 있습니다. 즉, 명령이 실패 (체인) 된 후 스크립트를 중지하도록 선택하거나 아무 일도 일어나지 않은 것처럼 계속할 수 있습니다!
사용 지침은 ReadMe 파일에 있습니다. 풀 요청을하거나 문제를 제출하십시오!
나는 그것을 언급 할 가치가 있다고 생각했다.
답변
@ TonyO’Hagan은 포괄적 인 shelljs
대답이지만 그의 대답의 동기 버전을 강조하고 싶습니다.
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) });