Я не уверен, что я прав, но я думаю, что вы ищете exec
и spawn
. См. related API documentation. В документации есть примеры для обеих команд.
exec
и spawn
exec
является "простой" вариант spawn
. Первый использует один обратный вызов для отправки отчета пользователю, когда команда завершена, и только когда она полностью завершена/не выполнена.
child = exec('cat *.js bad_file | wc -l',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
Поэтому в основном поставляется обратного вызова вызывается только, когда все, что было написано на стандартный вывод/STDERR доступен, полностью. После завершения процесса (с успехом или неудачей) только тогда вызывается обратный вызов, и пользователи (вы) могут воздействовать на него. Если это не удалось error
является правдой.
spawn
отличается, потому что вы можете слушать на stdout/stderr события. Сначала вы «запускаете» процесс. Функция spawn
возвращает ссылку на дочерний процесс.
var spawn = require('child_process').spawn;
var ls = spawn('ls', ['-lh', '/usr']);
ls
вот детский процесс, который вы породили. Он имеет два свойства (важно сейчас), stdout
и stderr
, которые являются излучателями событий. Они испускают событие data
. Когда материал написан на обоих потоках, вызываются обратные вызовы, зарегистрированные в событии data
.
ls.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
ls.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
Есть и другие важные события, конечно (проверьте документацию на самую актуальную и соответствующую информацию, конечно).
ls.on('close', function (code) {
console.log('child process exited with code ' + code);
});
Вы бы использовать spawn
, когда вы хотите, чтобы захватить вещи на стандартный вывод, например, в то время как процесс запущен.Хорошим примером может быть, если вы создавали задачу кодирования ffmpeg, для чего требуется несколько минут. Вы можете прослушивать stderr (потому что ffmpeg записывает информацию о ходе в stderr вместо stdout), чтобы разобрать информацию о «прогрессе».
Идя линия за линией с carrier
Существует хорошая дополнительная библиотека вы можете использовать вместе с spawn
. It's called carrier. Это помогает читать «строки» из stdout/stderr порожденных процессов. Это полезно, потому что параметр data
, переданный обратным вызовам, не обязательно содержит «полные» строки, разделенные \n
. carrier
помогает с этим. (Однако это не поможет вам зафиксировать прогресс ffmpeg на stderr, потому что в этом случае нет новых строк, написанных ffmpeg, это только возврат каретки, строка всегда переписывается в основном.)
Вы бы использовали его как этого
var carry = require("carrier").carry;
var child = spawn("command");
carry(child.stdout, function(line) {
console.log("stdout", line);
});
обещания и Deferreds
Если вы хотели бы использовать обещание/отложенный подход стиль, то вы могли бы сделать что-то вроде следующего using Q
, который используется AngularJS - или по крайней мере что-то очень (см. ссылку для полного учебника по обещаниям).
spawn
возвращает Emitter
объект, который не является обещанием. Таким образом, вы должны обернуть вызов на икру (see Using Deferreds).
var q = require("q");
var spawn = require("child_process").spawn;
var ls = function() {
var deferred = q.defer();
var ls = spawn("ls", ["-lh", "/usr"]);
ls.stdout.on("data", function(data) {
deferred.notify({stdout: true, data: data});
});
ls.stderr.on("data", function(data) {
deferred.notify({stderr: true, data: data});
});
ls.on("close", function(code) {
if (code === 0) {
deferred.resolve();
} else {
deferred.reject(code);
}
});
return deferred.promise;
};
ls()
Выполнив теперь обещание возвращается, который вы будете использовать, как и любое другое обещание. Когда он будет полностью разрешен, вызывается первый обратный вызов. Если возникает ошибка (процесс существует с кодом без нуля), вызывается обработчик ошибок. Пока команда прогрессирует, будет вызываться третий обратный вызов (уведомить обратный вызов).
ls().then(function() {
console.log("child process exited successfully");
}, function(err) {
console.log("child process exited with code " + err);
}, function(args) {
if (args.stdout) {
console.log("stdout: " + args.data);
} else {
console.log("stderr: " + args.data);
}
});
Когда что-то записывается в stderr, вы можете сразу же отклонить отклонение, то есть конструктивное решение. Возвращаясь к примеру ffmpeg, это не принесет вам пользы, потому что ffmpeg сплевывает общую информацию в stderr. Однако он может работать с другими командами.
Я думаю, что вы получите его :)
Примеры взяты из документации nodejs, так как от них хорошо известны.
Хотя я проголосовал за все ответы, я все еще изучаю их, и сегодня я выберу один из них. Спасибо всем! –
Этих ответов настолько хорошо, я буду чувствовать себя виноватыми, когда я выбираю только один из них :( –