Ich versuche immer noch, die Feinheiten zu erfassen, wie ich einen Linux- oder Windows-Shell-Befehl ausführen und die Ausgabe in node.js erfassen kann. letztendlich möchte ich so etwas machen ...
//pseudocode
output = run_command(cmd, args)
Das wichtige output
Element ist, dass es für eine Variable (oder ein Objekt) mit globalem Gültigkeitsbereich verfügbar sein muss. Ich habe die folgende Funktion ausprobiert, aber aus irgendeinem Grund werde ich undefined
auf der Konsole gedruckt ...
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" <------
Ich habe Probleme zu verstehen, wo der Code oben kaputt geht ... ein sehr einfacher Prototyp dieses Modells funktioniert ...
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" <----
Kann mir jemand helfen zu verstehen, warum try_this()
funktioniert und run_cmd()
nicht? FWIW muss ich verwenden child_process.spawn
, da child_process.exec
es ein Pufferlimit von 200 KB gibt.
Endgültige Lösung
Ich akzeptiere James Whites Antwort, aber das ist genau der Code, der für mich funktioniert hat ...
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);
quelle
me.stdout = "";
incmd_exec()
verhindern verkettenundefined
zu Beginn des Ergebnisses.Antworten:
Hier müssen drei Probleme behoben werden:
Erstens erwarten Sie ein synchrones Verhalten, wenn Sie stdout asynchron verwenden. Alle Aufrufe in Ihrer
run_cmd
Funktion sind asynchron, sodass der untergeordnete Prozess ausgelöst und sofort zurückgegeben wird, unabhängig davon, ob einige, alle oder keine der Daten von stdout ausgelesen wurden. Als solches, wenn Sie laufenSie erhalten alles, was gerade in foo.stdout gespeichert ist, und es gibt keine Garantie dafür, was das sein wird, da Ihr untergeordneter Prozess möglicherweise noch ausgeführt wird.
Zweitens ist stdout ein lesbarer Stream . 1) Das Datenereignis kann mehrmals aufgerufen werden, und 2) der Rückruf erhält einen Puffer und keine Zeichenfolge. Leicht zu beheben; nur ändern
in
Damit konvertieren wir unseren Puffer in eine Zeichenfolge und hängen diese Zeichenfolge an unsere stdout-Variable an.
Drittens können Sie nur dann wissen, dass Sie alle Ausgaben erhalten haben, wenn Sie das End-Ereignis erhalten. Dies bedeutet, dass wir einen weiteren Listener und Rückruf benötigen:
Ihr Endergebnis lautet also:
quelle
this.stdout = "";
innerhalb derrun()
Funktion tun , andernfalls wird Ihremconsole.log(foo.sdtout);
ein Präfix vorangestelltundefined
.Eine vereinfachte Version der akzeptierten Antwort (dritter Punkt) hat gerade für mich funktioniert.
Verwendung:
quelle
child.stdout.on('close', (errCode) => { console.log(errCode) } )
Ich habe das prägnanter verwendet:
es funktioniert perfekt. :) :)
quelle
sys.puts()
wurde 2011 veraltet (mit Node.js v0.2.3). Sie solltenconsole.log()
stattdessen verwenden.Am einfachsten ist es, einfach die ShellJS-Bibliothek zu verwenden ...
EXEC Beispiel:
ShellJs.org unterstützt viele gängige Shell-Befehle, die als NodeJS-Funktionen zugeordnet sind, darunter:
quelle
shell.exec("foo.sh arg1 arg2 ... ")
. Ihrfoo.sh
Skript kann diese mit Referenz$1
,$2
... etc.Ich hatte ein ähnliches Problem und schrieb schließlich eine Knotenerweiterung dafür. Sie können das Git-Repository auschecken. Es ist Open Source und kostenlos und all das gute Zeug!
https://github.com/aponxi/npm-execxi
Gebrauchsanweisungen finden Sie in der ReadMe-Datei . Fühlen Sie sich frei, Pull-Anfragen zu stellen oder Probleme einzureichen!
Ich fand es wert, es zu erwähnen.
quelle
@ TonyO'Hagan ist eine umfassende
shelljs
Antwort, aber ich möchte die synchrone Version seiner Antwort hervorheben:quelle
Synchroner Einzeiler:
require('child_process').execSync("echo 'hi'", function puts(error, stdout, stderr) { console.log(stdout) });
quelle
Es gibt einen variablen Konflikt in Ihrer
run_cmd
Funktion:Ändern Sie es einfach in Folgendes:
Um Fehler zu sehen, fügen Sie immer Folgendes hinzu:
BEARBEITEN Ihr Code schlägt fehl, weil Sie versuchen, ihn auszuführen,
dir
der nicht als separates eigenständiges Programm bereitgestellt wird. Es ist ein Befehl incmd
Bearbeitung. Wenn Sie mit dem Dateisystem spielen möchten, verwenden Sie nativerequire( 'fs' )
.Alternativ (was ich nicht empfehle) können Sie eine Batch-Datei erstellen, die Sie dann ausführen können. Beachten Sie, dass das Betriebssystem standardmäßig Batchdateien über auslöst
cmd
.quelle
C:\Windows\System32\netstat.exe
, liefert dies immer noch keine Ergebnisse ... Meine genaue Syntax warfoo = new run_cmd('netstat.exe', ['-an'], function (me, data){me.stdout=data;});
... Ich habe auch den vollständigen Weg bisher ohne Erfolg ausprobiertSie geben tatsächlich nichts von Ihrer Funktion run_cmd zurück.
Funktioniert gut. :) :)
quelle
return
erforderlich ist, solange Sie die Objektattribute richtig eingestellt habenEine versprochene Version der am meisten ausgezeichneten Antwort:
Benutzen:
quelle