Teraz jest o wiele łatwiej (6 lat później)!
Spawn zwraca obiekt childObject , za pomocą którego można następnie nasłuchiwać zdarzeń . Wydarzenia to:
- Klasa: ChildProcess
- Zdarzenie: „błąd”
- Wydarzenie: „wyjście”
- Wydarzenie: „zamknij”
- Zdarzenie: „odłącz”
- Wydarzenie: „wiadomość”
Istnieje również kilka obiektów z childObject , są to:
- Klasa: ChildProcess
- child.stdin
- child.stdout
- child.stderr
- child.stdio
- child.pid
- child.connected
- child.kill ([sygnał])
- child.send (message [, sendHandle] [, callback])
- child.disconnect ()
Zobacz więcej informacji na temat childObject: https://nodejs.org/api/child_process.html
Asynchroniczny
Jeśli chcesz uruchomić proces w tle, gdy węzeł nadal może działać, użyj metody asynchronicznej. Nadal możesz zdecydować się na wykonywanie akcji po zakończeniu procesu i gdy proces ma jakiekolwiek dane wyjściowe (na przykład, jeśli chcesz wysłać dane wyjściowe skryptu do klienta).
child_process.spawn (...); (Węzeł v0.1.90)
var spawn = require('child_process').spawn;
var child = spawn('node ./commands/server.js');
// You can also use a variable to save the output
// for when the script closes later
var scriptOutput = "";
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) {
//Here is where the output goes
console.log('stdout: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.stderr.setEncoding('utf8');
child.stderr.on('data', function(data) {
//Here is where the error output goes
console.log('stderr: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.on('close', function(code) {
//Here you can get the exit code of the script
console.log('closing code: ' + code);
console.log('Full output of script: ',scriptOutput);
});
Oto jak użyłbyś metody callback + asynchronicznej :
var child_process = require('child_process');
console.log("Node Version: ", process.version);
run_script("ls", ["-l", "/home"], function(output, exit_code) {
console.log("Process Finished.");
console.log('closing code: ' + exit_code);
console.log('Full output of script: ',output);
});
console.log ("Continuing to do node things while the process runs at the same time...");
// This function will output the lines from the script
// AS is runs, AND will return the full combined output
// as well as exit code when it's done (using the callback).
function run_script(command, args, callback) {
console.log("Starting Process.");
var child = child_process.spawn(command, args);
var scriptOutput = "";
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) {
console.log('stdout: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.stderr.setEncoding('utf8');
child.stderr.on('data', function(data) {
console.log('stderr: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.on('close', function(code) {
callback(scriptOutput,code);
});
}
Korzystając z powyższej metody, możesz wysłać każdy wiersz danych wyjściowych ze skryptu do klienta (na przykład za pomocą Socket.io do wysłania każdego wiersza, gdy otrzymujesz zdarzenia na stdout
lub stderr
).
Synchroniczny
Jeśli chcesz, aby węzeł zatrzymał to, co robi i poczekał, aż skrypt się zakończy , możesz użyć wersji synchronicznej:
child_process.spawnSync (...);(Węzeł v0.11.12 +)
Problemy z tą metodą:
- Jeśli wykonanie skryptu zajmie trochę czasu, serwer zawiesi się na ten czas!
- Wyjście standardowe zostanie zwrócone dopiero po zakończeniu działania skryptu . Ponieważ jest synchroniczny, nie może być kontynuowany do zakończenia bieżącej linii. Dlatego nie jest w stanie przechwycić zdarzenia „stdout” do czasu zakończenia linii odradzania.
Jak tego użyć:
var child_process = require('child_process');
var child = child_process.spawnSync("ls", ["-l", "/home"], { encoding : 'utf8' });
console.log("Process finished.");
if(child.error) {
console.log("ERROR: ",child.error);
}
console.log("stdout: ",child.stdout);
console.log("stderr: ",child.stderr);
console.log("exist code: ",child.status);
python
, nie zapomnij przekazać-u
flagi, aby nie buforował wyjścia konsoli, w przeciwnym razie będzie wyglądać tak, jakby skrypt nie był