Сейчас (6 лет спустя) все намного проще!
Spawn возвращает childObject , с помощью которого вы затем можете прослушивать события . События:
- Класс: ChildProcess
- Событие: 'ошибка'
- Событие: «выход»
- Событие: «закрыть»
- Событие: "отключиться"
- Событие: "сообщение"
Также есть набор объектов из childObject , это:
- Класс: ChildProcess
- child.stdin
- child.stdout
- child.stderr
- child.stdio
- child.pid
- child.connected
- child.kill ([сигнал])
- child.send (сообщение [, sendHandle] [, обратный вызов])
- child.disconnect ()
См. Дополнительную информацию о childObject здесь: https://nodejs.org/api/child_process.html
Асинхронный
Если вы хотите запустить процесс в фоновом режиме, в то время как узел все еще может продолжать выполнение, используйте асинхронный метод. Вы по-прежнему можете выполнять действия после завершения процесса и когда у процесса есть какие-либо выходные данные (например, если вы хотите отправить выходные данные сценария клиенту).
child_process.spawn (...); (Узел 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);
});
Вот как вы могли бы использовать асинхронный метод обратного вызова :
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);
});
}
Используя описанный выше метод, вы можете отправлять каждую строку вывода из сценария клиенту (например, используя Socket.io для отправки каждой строки при получении событий на stdout
или stderr
).
Синхронный
Если вы хотите, чтобы node прекратил свои действия и дождался завершения скрипта , вы можете использовать синхронную версию:
child_process.spawnSync (...); (Узел v0.11.12 +)
Проблемы с этим методом:
- Если сценарий требует времени для завершения, ваш сервер зависнет на это время!
- Стандартный вывод будет возвращен только после того, как скрипт завершит работу . Поскольку он синхронный, он не может продолжаться, пока не закончится текущая строка. Следовательно, он не может захватить событие 'stdout', пока не завершится линия появления.
Как это использовать:
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
, не забудьте передать-u
флаг, чтобы он не буферизовал вывод консоли, иначе он будет выглядеть так, как будто скрипт не работает stackoverflow.com/a/49947671/906265