Процесс-потомк
Исходный код: lib/child_process.js
Модуль node:child_process предоставляет возможность запуска дочерних процессов подобным, но не идентичным, способом, как в popen(3). Данная возможность в основном реализована функцией child_process.spawn():
const { spawn } = require('node:child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
}); copy По умолчанию, каналы для stdin, stdout, и stderr устанавливаются между родительским процессом Node.js и запущенным дочерним процессом. Эти каналы имеют ограниченную (и зависящую от платформы) емкость. Если дочерний процесс записывает в stdout с превышением этой лимита без захвата вывода, дочерний процесс блокируется, ожидая, пока буфер канала примет больше данных. Это идентично поведению каналов в оболочке. Используйте параметр { stdio: 'ignore' } если вывод не будет потреблен.
Поиск команды выполняется с использованием переменной окружения options.env.PATH если env присутствует в объекте options. В противном случае используется process.env.PATH. Если options.env установлена без PATH, поиск на Unix выполняется в стандартном пути поиска /usr/bin:/bin (см. руководство операционной системы для execvpe/execvp), а на Windows используется переменная окружения текущего процесса PATH.
В Windows, переменные окружения регистронезависимые. Node.js лексикографически сортирует ключи env и использует первый, который регистронезависимо совпадает. Только первая (в лексикографическом порядке) запись будет передана дочернему процессу. Это может привести к проблемам в Windows при передаче объектов в параметр env с несколькими вариантами одного и того же ключа, например, PATH и Path.
Метод child_process.spawn() запускает дочерний процесс асинхронно, не блокируя цикл событий Node.js. Функция child_process.spawnSync() предоставляет эквивалентную функциональность синхронным способом, блокируя цикл событий, пока запущенный процесс не завершит работу или не будет прерван.
Для удобства, модуль node:child_process предоставляет несколько синхронных и асинхронных альтернатив методам child_process.spawn() и child_process.spawnSync(). Каждая из этих альтернатив реализована на основе child_process.spawn() или child_process.spawnSync().
-
child_process.exec(): запускает оболочку и выполняет команду внутри этой оболочки, передаваяstdoutиstderrв функцию обратного вызова при завершении. -
child_process.execFile(): аналогичноchild_process.exec(), за исключением того, что запускает команду непосредственно без предварительного запуска оболочки по умолчанию. -
child_process.fork(): запускает новый процесс Node.js и вызывает указанный модуль с каналом IPC, который позволяет отправлять сообщения между родительским и дочерним процессами. -
child_process.execSync(): синхронная версияchild_process.exec(), которая заблокирует цикл событий Node.js. -
child_process.execFileSync(): синхронная версияchild_process.execFile(), которая заблокирует цикл событий Node.js.
В некоторых случаях, таких как автоматизация сценариев оболочки, синхронные аналоги могут быть более удобными. Однако во многих случаях синхронные методы могут значительно повлиять на производительность из-за остановки цикла событий, пока дочерние процессы не завершат работу.
END_OF_DOCUMENT_MARKERАсинхронное создание процессов
Методы child_process.spawn(), child_process.fork(), child_process.exec() и child_process.execFile() следуют общепринятому шаблону асинхронного программирования, характерному для других API Node.js.
Каждый из методов возвращает экземпляр ChildProcess. Эти объекты реализуют API Node.js EventEmitter, позволяя родительскому процессу регистрировать обработчики событий, которые вызываются при наступлении определённых событий в течение жизненного цикла дочернего процесса.
Методы child_process.exec() и child_process.execFile() дополнительно позволяют указать необязательную функцию callback, которая вызывается при завершении дочернего процесса.
Создание процессов для файлов BAT и CMD в Windows
Значение различия между child_process.exec() и child_process.execFile() может меняться в зависимости от платформы. В операционных системах типа Unix (Unix, Linux, macOS) child_process.execFile() может быть более эффективным, так как по умолчанию не запускает оболочку. Однако в Windows файлы BAT и CMD не являются исполняемыми сами по себе без терминала и поэтому не могут быть запущены с помощью child_process.execFile(). При работе в Windows файлы BAT и CMD могут быть вызваны с помощью child_process.spawn() с опцией shell, с child_process.exec() или путём создания процесса cmd.exe и передачи файла .bat или .cmd в качестве аргумента (что выполняют опция shell и child_process.exec()). В любом случае, если имя файла скрипта содержит пробелы, оно должно быть заключено в кавычки.
// On Windows Only...
const { spawn } = require('node:child_process');
const bat = spawn('cmd.exe', ['/c', 'my.bat']);
bat.stdout.on('data', (data) => {
console.log(data.toString());
});
bat.stderr.on('data', (data) => {
console.error(data.toString());
});
bat.on('exit', (code) => {
console.log(`Child exited with code ${code}`);
}); copy // OR...
const { exec, spawn } = require('node:child_process');
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
// Script with spaces in the filename:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// or:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
}); copy
child_process.exec(command[, options][, callback])
-
command<строка> Команда для выполнения с аргументами, разделёнными пробелами. -
options<объект>-
cwd<строка> | <URL> Текущий рабочий каталог дочернего процесса. По умолчанию:process.cwd(). -
env<объект> Параметры среды в формате ключ-значение. По умолчанию:process.env. -
encoding<строка> По умолчанию:'utf8' -
shell<строка> Оболочка для выполнения команды. См. Требования к оболочке и Стандартную оболочку Windows. По умолчанию:'/bin/sh'в Unix,process.env.ComSpecв Windows. -
signal<AbortSignal> позволяет прервать дочерний процесс с помощью AbortSignal. -
timeout<число> По умолчанию:0 -
maxBuffer<число> Максимальный объём данных в байтах, разрешённый на stdout или stderr. При превышении этого значения дочерний процесс завершается, а любые выводимые данные усекаются. См. замечание в разделеmaxBufferи Unicode. По умолчанию:1024 * 1024. -
killSignal<строка> | <целое число> По умолчанию:'SIGTERM' -
uid<число> Устанавливает идентификатор пользователя процесса (см.setuid(2)). -
gid<число> Устанавливает идентификатор группы процесса (см.setgid(2)). -
windowsHide<логическое значение> Скрыть окно консоли дочернего процесса, которое обычно создаётся в Windows. По умолчанию:false.
-
-
callback<функция> вызывается с результатом при завершении процесса. - Возвращает: <ChildProcess>
Создаёт оболочку и выполняет команду command в этой оболочке, буферизируя любой генерируемый вывод. Строка command, переданная функции exec, обрабатывается непосредственно оболочкой, и специальные символы (зависит от оболочки) необходимо обработать соответствующим образом:
const { exec } = require('node:child_process');
exec('"/path/to/test file/test.sh" arg1 arg2');
// Double quotes are used so that the space in the path is not interpreted as
// a delimiter of multiple arguments.
exec('echo "The \\$HOME variable is $HOME"');
// The $HOME variable is escaped in the first instance, but not in the second. copy Никогда не передавайте необработанные данные пользователя этой функции. Любые данные, содержащие метасимволы оболочки, могут быть использованы для запуска произвольных команд.
Если функция callback предоставлена, она вызывается с аргументами (error, stdout, stderr). В случае успеха error будет null. В случае ошибки error будет экземпляром Error. Свойство error.code будет кодом завершения процесса. По соглашению, любой код завершения, отличный от 0, указывает на ошибку. error.signal будет сигналом, завершившим процесс.
Аргументы stdout и stderr переданные обработчику, будут содержать выводимые данные stdout и stderr дочернего процесса. По умолчанию Node.js будет декодировать вывод как UTF-8 и передавать строки в обработчик. Опция encoding может быть использована для указания кодировки символов, используемой для декодирования выводимых данных stdout и stderr. Если encoding равняется 'buffer', или является не распознанной кодировкой символов, вместо этого в обработчик будут переданы объекты Buffer.
const { exec } = require('node:child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
}); copy Если timeout больше 0, родительский процесс отправит сигнал, определённый свойством killSignal (по умолчанию 'SIGTERM') если дочерний процесс будет выполняться дольше timeout миллисекунд.
В отличие от системного вызова exec(3) POSIX, child_process.exec() не заменяет существующий процесс и использует оболочку для выполнения команды.
Если этот метод вызывается в виде его util.promisify()-версии, он возвращает промис для объекта Promise с свойствами Object и stdout . Возвращённый экземпляр ChildProcess прикрепляется к Promise в качестве свойства child. В случае ошибки (включая любую ошибку, приводящую к коду завершения, отличному от 0), возвращается отклонённый промис с тем же объектом error, который был передан в обработчик, но с двумя дополнительными свойствами stdout и stderr.
const util = require('node:util');
const exec = util.promisify(require('node:child_process').exec);
async function lsExample() {
const { stdout, stderr } = await exec('ls');
console.log('stdout:', stdout);
console.error('stderr:', stderr);
}
lsExample(); copy Если опция signal включена, вызов .abort() на соответствующем AbortController аналогичен вызову .kill() на дочернем процессе, за исключением того, что ошибка, переданная в обработчик, будет ошибкой AbortError:
const { exec } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const child = exec('grep ssh', { signal }, (error) => {
console.error(error); // an AbortError
});
controller.abort(); copy
child_process.execFile(file[, args][, options][, callback])
-
file<строка> Имя или путь к исполняемому файлу для запуска. -
args<массив строк> Список строковых аргументов. -
options<Объект>-
cwd<строка> | <URL> Текущая рабочая директория дочернего процесса. -
env<Объект> Параметры окружения в формате ключ-значение. По умолчанию:process.env. -
encoding<строка> По умолчанию:'utf8' -
timeout<число> По умолчанию:0 -
maxBuffer<число> Максимальный объем данных в байтах, разрешенный для stdout или stderr. Если превзойден, дочерний процесс завершается, а любой вывод усекается. См. замечание вmaxBufferи Unicode. По умолчанию:1024 * 1024. -
killSignal<строка> | <целое число> По умолчанию:'SIGTERM' -
uid<число> Устанавливает идентификатор пользователя процесса (см.setuid(2)). -
gid<число> Устанавливает идентификатор группы процесса (см.setgid(2)). -
windowsHide<логическое> Скрыть консольное окно дочернего процесса, которое обычно создается на системах Windows. По умолчанию:false. -
false<логическое> Отключение цитирования или экранирования аргументов в Windows. Игнорируется в Unix. По умолчанию:false. -
shell<логическое> | <строка> Еслиtrue, запускаетcommandвнутри оболочки. Использует'/bin/sh'в Unix иprocess.env.ComSpecв Windows. Можно указать другую оболочку в виде строки. См. Требования к оболочке и Стандартная оболочка Windows. По умолчанию:false(без оболочки). -
signal<AbortSignal> позволяет прервать дочерний процесс с помощью AbortSignal.
-
-
callback<Функция> Вызывается с выводом, когда процесс завершается. - Возвращает: <Дочерний процесс>
Функция child_process.execFile() похожа на child_process.exec(), за исключением того, что по умолчанию не запускает оболочку. Вместо этого указанный исполняемый файл file запускается непосредственно как новый процесс, что немного эффективнее, чем child_process.exec().
Поддерживаются те же параметры, что и в child_process.exec(). Поскольку оболочка не запускается, такие функции, как перенаправление ввода-вывода и подстановка файлов, не поддерживаются.
const { execFile } = require('node:child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
}); copy Аргументы stdout и stderr, передаваемые в обратный вызов, будут содержать вывод stdout и stderr дочернего процесса. По умолчанию Node.js будет декодировать вывод как UTF-8 и передавать строки в обратный вызов. Параметр encoding можно использовать для указания кодировки символов, используемой для декодирования вывода stdout и stderr. Если encoding является 'buffer', или это неизвестная кодировка символов, в обратный вызов вместо этого будут передаваться объекты Buffer.
Если этот метод вызван в качестве его util.promisify() версии, он возвращает Promise для Object с stdout и stderr свойствами. Возвращённый экземпляр ChildProcess прикрепляется к Promise в качестве свойства child . В случае ошибки (включая любую ошибку, приводящую к коду возврата, отличному от 0), возвращается отклоненное обещание, с тем же объектом error, который был передан в обратный вызов, но с двумя дополнительными свойствами stdout и stderr.
const util = require('node:util');
const execFile = util.promisify(require('node:child_process').execFile);
async function getVersion() {
const { stdout } = await execFile('node', ['--version']);
console.log(stdout);
}
getVersion(); copy Если параметр shell включен, не передавайте необработанные данные пользователя в эту функцию. Любой ввод, содержащий метасимволы оболочки, может быть использован для запуска произвольного выполнения команд.
Если параметр signal включён, вызов .abort() для соответствующего AbortController аналогичен вызову .kill() для дочернего процесса, за исключением того, что ошибка, передаваемая в обратный вызов, будет AbortError.
const { execFile } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const child = execFile('node', ['--version'], { signal }, (error) => {
console.error(error); // an AbortError
});
controller.abort(); copy
child_process.fork(modulePath[, args][, options])
-
modulePath<string> | <URL> Модуль для выполнения в дочернем процессе. -
args<string[]> Список строковых аргументов. -
options<Object>-
cwd<string> | <URL> Текущая рабочая директория дочернего процесса. -
detached<boolean> Подготовка дочернего процесса к независимому выполнению от родительского процесса. Конкретное поведение зависит от платформы, см.options.detached. -
env<Object> Параметры окружения в формате ключ-значение. По умолчанию:process.env. -
execPath<string> Исполняемый файл для создания дочернего процесса. -
execArgv<string[]> Список строковых аргументов, передаваемых исполняемому файлу. По умолчанию:process.execArgv. -
gid<number> Устанавливает идентификатор группы процесса (см.setgid(2)). -
serialization<string> Указывает тип сериализации для обмена сообщениями между процессами. Возможные значения:'json'и'advanced'. Подробнее см. Дополнительно о сериализации. По умолчанию:'json'. -
signal<AbortSignal> Позволяет завершить дочерний процесс с помощью AbortSignal. -
killSignal<string> | <integer> Код сигнала, используемый для завершения процесса при истечении таймаута или сигнале прерывания. По умолчанию:'SIGTERM'. -
silent<boolean> Еслиtrue, стандартные потоки ввода, вывода и ошибок дочернего процесса будут направлены в родительский процесс, в противном случае они будут унаследованы от родительского процесса. См. параметры'pipe'и'inherit'вchild_process.spawn()'sstdioдля более подробной информации. По умолчанию:false. -
stdio<Array> | <string> См.child_process.spawn()'sstdio. При указании данного параметра он переопределяетsilent. Если используется вариант массива, он должен содержать ровно один элемент со значением'ipc', в противном случае будет выброшено исключение. Например,[0, 1, 2, 'ipc']. -
uid<number> Устанавливает идентификатор пользователя процесса (см.setuid(2)). -
windowsVerbatimArguments<boolean> На Windows не происходит цитирования или экранирования аргументов. Игнорируется в Unix. По умолчанию:false. -
timeout<number> Максимальное время выполнения процесса в миллисекундах. По умолчанию:undefined.
-
- Возвращает: <ChildProcess>
Метод child_process.fork() — это специальный случай child_process.spawn(), используемый для запуска новых процессов Node.js. Как и child_process.spawn(), возвращает объект ChildProcess. Возвращаемый объект ChildProcess будет иметь встроенный канал связи, позволяющий передавать сообщения между родительским и дочерним процессами. Подробнее см. subprocess.send().
Обратите внимание, что запущенные дочерние процессы Node.js независимы от родительского, за исключением установленного канала IPC. Каждый процесс имеет свою собственную память с собственными экземплярами V8. Из-за дополнительных затрат на ресурсы не рекомендуется запускать большое количество дочерних процессов Node.js.
По умолчанию child_process.fork() запустит новые экземпляры Node.js, используя process.execPath родительского процесса. Свойство execPath в объекте options позволяет использовать альтернативный путь выполнения.
Процессы Node.js, запущенные с настраиваемым execPath, будут общаться с родительским процессом через файловый дескриптор (fd), идентифицированный переменной окружения NODE_CHANNEL_FD в дочернем процессе.
В отличие от системного вызова POSIX fork(2), child_process.fork() не клонирует текущий процесс.
Параметр shell в child_process.spawn() не поддерживается child_process.fork() и будет проигнорирован при установке.
Если параметр signal включён, вызов .abort() для соответствующего AbortController аналогичен вызову .kill() в дочернем процессе, за исключением того, что ошибка, переданная в обратный вызов, будет типом AbortError:
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Hello from ${process.argv[2]}!`);
}, 1_000);
} else {
const { fork } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const child = fork(__filename, ['child'], { signal });
child.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
} copy
child_process.spawn(command[, args][, options])
-
command<string> Команда для выполнения. -
args<string[]> Список строковых аргументов. -
options<Object>-
cwd<string> | <URL> Текущий рабочий каталог дочернего процесса. -
env<Object> Параметры окружения в формате ключ-значение. По умолчанию:process.env. -
argv0<string> Явно задайте значениеargv[0], передаваемое дочернему процессу. Будет установлено вcommandпри отсутствии явного указания. -
stdio<Array> | <string> Настройка stdio дочернего процесса (см.options.stdio). -
detached<boolean> Подготовьте дочерний процесс к запуску независимо от родительского процесса. Конкретное поведение зависит от платформы, см.options.detached). -
uid<number> Устанавливает идентификатор пользователя процесса (см.setuid(2)). -
gid<number> Устанавливает идентификатор группы процесса (см.setgid(2)). -
serialization<string> Укажите тип сериализации, используемой для обмена сообщениями между процессами. Возможные значения:'json'и'advanced'. Подробнее см. Дополнительная сериализация. По умолчанию:'json'. -
shell<boolean> | <string> Еслиtrue, выполнитcommandвнутри оболочки. Использует'/bin/sh'на Unix иprocess.env.ComSpecна Windows. Другую оболочку можно указать в виде строки. См. Требования к оболочке и Стандартная оболочка Windows. По умолчанию:false(без оболочки). -
windowsVerbatimArguments<boolean> На Windows отключение цитирования и экранирования аргументов. Игнорируется на Unix. Устанавливается вtrueавтоматически, когдаshellзадан и равен CMD. По умолчанию:false. -
windowsHide<boolean> Скрыть окно консоли дочернего процесса, которое обычно создаётся на Windows. По умолчанию:false. -
signal<AbortSignal> позволяет прервать дочерний процесс с помощью AbortSignal. -
timeout<number> Максимальное время выполнения процесса в миллисекундах. По умолчанию:undefined. -
killSignal<string> | <integer> Значение сигнала, которое будет использовано при завершении дочернего процесса по таймауту или сигналу прерывания. По умолчанию:'SIGTERM'.
-
- Возвращает: <ChildProcess>
Метод child_process.spawn() запускает новый процесс с заданными command, а аргументы командной строки передаются в args. Если опущено, args по умолчанию является пустым массивом.
Если опция shell включена, не передавайте необработанные данные пользователя в эту функцию. Любые данные, содержащие метасимволы оболочки, могут быть использованы для запуска произвольных команд.
Дополнительные параметры можно указать в третьем аргументе, со следующими значениями по умолчанию:
const defaults = {
cwd: undefined,
env: process.env,
}; copy Используйте cwd для указания рабочего каталога, из которого запускается процесс. Если не указан, по умолчанию используется текущий рабочий каталог. Если указан, но путь не существует, дочерний процесс генерирует ошибку ENOENT и завершается немедленно. ENOENT также генерируется, если команда не найдена.
Используйте env для указания переменных среды, которые будут видны новому процессу, по умолчанию это process.env.
undefined значения в env будут проигнорированы.
Пример запуска ls -lh /usr, захвата stdout, stderr и кода завершения:
const { spawn } = require('node:child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
}); copy Пример: Очень подробный способ запуска ps ax | grep ssh
const { spawn } = require('node:child_process');
const ps = spawn('ps', ['ax']);
const grep = spawn('grep', ['ssh']);
ps.stdout.on('data', (data) => {
grep.stdin.write(data);
});
ps.stderr.on('data', (data) => {
console.error(`ps stderr: ${data}`);
});
ps.on('close', (code) => {
if (code !== 0) {
console.log(`ps process exited with code ${code}`);
}
grep.stdin.end();
});
grep.stdout.on('data', (data) => {
console.log(data.toString());
});
grep.stderr.on('data', (data) => {
console.error(`grep stderr: ${data}`);
});
grep.on('close', (code) => {
if (code !== 0) {
console.log(`grep process exited with code ${code}`);
}
}); copy Пример проверки на ошибку spawn:
const { spawn } = require('node:child_process');
const subprocess = spawn('bad_command');
subprocess.on('error', (err) => {
console.error('Failed to start subprocess.');
}); copy На некоторых платформах (macOS, Linux) значение argv[0] используется для заголовка процесса, а на других (Windows, SunOS) - command.
Node.js перезаписывает argv[0] на process.execPath при запуске, поэтому process.argv[0] в дочернем процессе Node.js не будет совпадать с argv0 параметром, переданным в spawn из родительского процесса. Получите его с помощью свойства process.argv0 вместо этого.
Если опция signal включена, вызов .abort() для соответствующего AbortController аналогичен вызову .kill() для дочернего процесса, за исключением того, что ошибка, переданная в обратный вызов, будет AbortError:
const { spawn } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const grep = spawn('grep', ['ssh'], { signal });
grep.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process copy
options.detached
На Windows, установка options.detached в true позволяет дочернему процессу продолжать работу после завершения родительского. У дочернего процесса будет собственное окно консоли. После активации для дочернего процесса, его нельзя отключить.
На платформах, отличных от Windows, если options.detached установлено в true, дочерний процесс станет лидером новой группы и сессии процессов. Дочерние процессы могут продолжать работу после завершения родительского независимо от того, откреплены они или нет. Для получения дополнительной информации см. setsid(2).
По умолчанию родительский процесс будет ждать завершения откреплённого дочернего процесса. Чтобы предотвратить ожидание родительским процессом завершения данного subprocess, используйте метод subprocess.unref(). Это заставит цикл событий родителя не включать дочерний процесс в счётчик ссылок, что позволит родителю завершиться независимо от дочернего, если между ними нет установленного канала IPC.
При использовании опции detached для запуска длительно работающего процесса, процесс не будет оставаться в фоновом режиме после завершения родительского, если ему не предоставлена настройка stdio без подключения к родителю. Если у родительского stdio наследуется дочерним, дочерний процесс останется присоединённым к контролирующему терминалу.
Пример длительно работающего процесса, при откреплении и игнорировании родительских stdio дескрипторов файлов для игнорирования завершения родителя:
const { spawn } = require('node:child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
});
subprocess.unref(); copy В качестве альтернативы можно перенаправить вывод дочернего процесса в файлы:
const fs = require('node:fs');
const { spawn } = require('node:child_process');
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');
const subprocess = spawn('prg', [], {
detached: true,
stdio: [ 'ignore', out, err ],
});
subprocess.unref(); copy
options.stdio
Опция options.stdio используется для конфигурации каналов, установленных между родительским и дочерним процессом. По умолчанию stdin, stdout и stderr дочернего процесса перенаправляются на соответствующие потоки subprocess.stdin, subprocess.stdout и subprocess.stderr объекта ChildProcess. Это эквивалентно установке options.stdio в ['pipe', 'pipe', 'pipe'].
Для удобства options.stdio может быть одной из следующих строк:
-
'pipe': эквивалентно['pipe', 'pipe', 'pipe'](по умолчанию) -
'overlapped': эквивалентно['overlapped', 'overlapped', 'overlapped'] -
'ignore': эквивалентно['ignore', 'ignore', 'ignore'] -
'inherit': эквивалентно['inherit', 'inherit', 'inherit']или[0, 1, 2]
В противном случае значение options.stdio представляет собой массив, где каждый индекс соответствует fd в дочернем процессе. Fd 0, 1 и 2 соответствуют stdin, stdout и stderr соответственно. Дополнительные fd могут быть указаны для создания дополнительных каналов связи между родительским и дочерним процессами.
-
'pipe': Создать канал между дочерним и родительским процессами. Родительский конец канала доступен родителю как свойство объектаchild_processкакsubprocess.stdio[fd]. Каналы, созданные для fds 0, 1 и 2, также доступны какsubprocess.stdin,subprocess.stdoutиsubprocess.stderrсоответственно. Это не реальные Unix каналы, поэтому дочерний процесс не может использовать их с помощью файлов-дескрипторов, например,/dev/fd/2или/dev/stdout. -
'overlapped': Аналогично'pipe', но флагFILE_FLAG_OVERLAPPEDустановлен для дескриптора. Это необходимо для перекрывающегося ввода-вывода (overlapped I/O) ввода-вывода stdin дочернего процесса. Подробнее см. документацию. Абсолютно аналогично'pipe'на системах, не Windows. -
'ipc': Создать канал IPC для передачи сообщений/файловых дескрипторов между родителем и ребенком. УChildProcessможет быть не более одного файлового дескриптора IPC. Установка этого параметра активирует методsubprocess.send(). Если дочерний процесс — это процесс Node.js, наличие канала IPC активирует методыprocess.send()иprocess.disconnect(), а также события'disconnect'и'message'внутри дочернего процесса.Доступ к файловому дескриптору канала IPC любым способом, кроме
process.send(), или использование канала IPC с дочерним процессом, не являющимся экземпляром Node.js, не поддерживается. -
'ignore': Указывает Node.js игнорировать fd в дочернем процессе. Хотя Node.js всегда открывает fds 0, 1 и 2 для создаваемых процессов, установка fd в'ignore'заставит Node.js открыть/dev/nullи прикрепить его к fd дочернего процесса. -
'inherit': Передать соответствующий поток ввода-вывода родительскому процессу. В первых трех позициях это эквивалентноprocess.stdin,process.stdout, иprocess.stderr, соответственно. В любой другой позиции, эквивалентно'ignore'. -
<Поток> объект: Поделиться потоком для чтения или записи, который относится к tty, файлу, сокету или каналу с дочерним процессом. Базовый файловый дескриптор потока дублируется в дочернем процессе на fd, соответствующий индексу в массиве
stdio. Поток должен иметь базовый дескриптор (файловые потоки не начинаются до события'open'). -
Положительное целое число: Целое значение интерпретируется как открытый файловый дескриптор в родительском процессе. Он разделяется с дочерним процессом, аналогично тому, как могут быть разделены объекты <Поток>. Передача сокетов не поддерживается в Windows.
-
null,undefined: Использовать значение по умолчанию. Для файловых дескрипторов ввода-вывода 0, 1 и 2 (то есть stdin, stdout и stderr) создается канал. Для fd 3 и выше значение по умолчанию'ignore'.
const { spawn } = require('node:child_process');
// Child will use parent's stdios.
spawn('prg', [], { stdio: 'inherit' });
// Spawn child sharing only stderr.
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });
// Open an extra fd=4, to interact with programs presenting a
// startd-style interface.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); copy Важно отметить, что при установлении канала IPC между родительским и дочерним процессами, и если дочерний процесс — процесс Node.js, дочерний процесс запускается без ссылки на канал IPC (используя unref()) до тех пор, пока дочерний процесс не зарегистрирует обработчик события 'disconnect' или 'message'. Это позволяет дочернему процессу выйти нормально, не блокируя процесс открытым каналом IPC.
См. также: child_process.exec() и child_process.fork().
Синхронное создание процесса
Методы child_process.spawnSync(), child_process.execSync() и child_process.execFileSync() являются синхронными и заблокируют цикл событий Node.js, приостанавливая выполнение любого дополнительного кода до выхода запущенного процесса.
Блокирующие вызовы, подобные этим, в основном полезны для упрощения задач сценариев общего назначения и для упрощения загрузки/обработки конфигурации приложения при запуске.
child_process.execFileSync(file[, args][, options])
-
file<строка> Имя или путь к исполняемому файлу для запуска. -
args<массив строк> Список строковых аргументов. -
options<Объект>-
cwd<строка> | <URL> Текущий рабочий каталог дочернего процесса. -
input<строка> | <Буфер> | <Массив типов> | <DataView> Значение, которое будет передано как stdin запущенному процессу. Еслиstdio[0]установлено в'pipe', это значение переопределитstdio[0]. -
stdio<строка> | <Массив> Настройка stdio дочернего процесса. См.child_process.spawn()иstdio.stderrпо умолчанию будет выводиться в stderr родительского процесса, если не указаноstdio. По умолчанию:'pipe'. -
env<Объект> Параметры среды в формате ключ-значение. По умолчанию:process.env. -
uid<число> Устанавливает идентификатор пользователя процесса (см.setuid(2)). -
gid<число> Устанавливает идентификатор группы процесса (см.setgid(2)). -
timeout<число> Максимальное время выполнения процесса в миллисекундах. По умолчанию:undefined. -
killSignal<строка> | <целое> Значение сигнала, используемого при завершении запущенного процесса. По умолчанию:'SIGTERM'. -
maxBuffer<число> Максимальный объём данных в байтах на stdout или stderr. При превышении этого значения, дочерний процесс завершается. См. примечание вmaxBufferи Unicode. По умолчанию:1024 * 1024. -
encoding<строка> Кодировка, используемая для всех входов и выходов stdio. По умолчанию:'buffer'. -
windowsHide<логическое значение> Скрыть окно консоли подпроцесса, которое обычно создаётся на системах Windows. По умолчанию:false. -
shell<логическое значение> | <строка> Еслиtrue, выполняетcommandвнутри оболочки. Использует'/bin/sh'на Unix иprocess.env.ComSpecна Windows. Можно указать другую оболочку в качестве строки. См. Требования к оболочке и Стандартная оболочка Windows. По умолчанию:false(без оболочки).
-
- Возвращает: <Буфер> | <строка> Вывод stdout из команды.
Метод child_process.execFileSync() в целом идентичен child_process.execFile(), за исключением того, что метод не вернётся, пока дочерний процесс не закроется полностью. При обнаружении таймаута и отправке killSignal, метод не вернётся, пока процесс полностью не завершится.
Если дочерний процесс перехватывает и обрабатывает сигнал SIGTERM и не завершается, родительский процесс всё равно будет ждать завершения дочернего процесса.
Если процесс превышает время ожидания или имеет код выхода, отличный от нуля, этот метод выбросит Error, который будет включать полный результат базового child_process.spawnSync().
Если параметр shell включён, не передавайте необработанные данные пользователя в эту функцию. Любой ввод, содержащий символы метаязыка оболочки, может использоваться для запуска произвольных команд.
const { execFileSync } = require('node:child_process');
try {
const stdout = execFileSync('my-script.sh', ['my-arg'], {
// Capture stdout and stderr from child process. Overrides the
// default behavior of streaming child stderr to the parent stderr
stdio: 'pipe',
// Use utf8 encoding for stdio pipes
encoding: 'utf8',
});
console.log(stdout);
} catch (err) {
if (err.code) {
// Spawning child process failed
console.error(err.code);
} else {
// Child was spawned but exited with non-zero exit code
// Error contains any stdout and stderr from the child
const { stdout, stderr } = err;
console.error({ stdout, stderr });
}
} copy
child_process.execSync(command[, options])
-
command<string> Команда для выполнения. -
options<Object>-
cwd<string> | <URL> Текущая рабочая директория дочернего процесса. -
input<string> | <Buffer> | <TypedArray> | <DataView> Значение, которое будет передано как stdin дочернему процессу. Еслиstdio[0]установлено в'pipe', это значение переопределитstdio[0]. -
stdio<Object> Настройка stdio дочернего процесса. Смотритеchild_process.spawn()'sstdio.stderrпо умолчанию будет выводиться в stderr родительского процесса, если не указаноstdio. По умолчанию:'pipe'. -
env<Object> Переменные среды в формате ключ-значение. По умолчанию:process.env. -
shell<string> Оболочка для выполнения команды. См. Требования к оболочке и Стандартная оболочка Windows. По умолчанию:'/bin/sh'на Unix,process.env.ComSpecна Windows. -
uid<number> Устанавливает идентификатор пользователя процесса. (См.setuid(2)). -
gid<number> Устанавливает идентификатор группы процесса. (См.setgid(2)). -
timeout<number> Максимальное время работы процесса в миллисекундах. По умолчанию:undefined. -
killSignal<string> | <integer> Значение сигнала, используемого для завершения дочернего процесса. По умолчанию:'SIGTERM'. -
maxBuffer<number> Максимальный объем данных в байтах для stdout или stderr. При превышении этого значения дочерний процесс завершается, а вывод обрезается. См. замечание вmaxBufferи Unicode. По умолчанию:1024 * 1024. -
encoding<string> Кодировка, используемая для всех входных и выходных данных stdio. По умолчанию:'buffer'. -
windowsHide<boolean> Скрыть консольное окно дочернего процесса, которое обычно создается на системах Windows. По умолчанию:false.
-
- Возвращает: <Buffer> | <string> Вывод stdout команды.
Метод child_process.execSync() в целом идентичен child_process.exec() за исключением того, что он не возвращает значение, пока дочерний процесс не закроется полностью. При возникновении таймаута и отправке сигнала killSignal, метод не вернет значение, пока процесс не завершит свою работу. Если дочерний процесс перехватывает и обрабатывает сигнал SIGTERM, но не завершается, родительский процесс будет ожидать завершения дочернего процесса.
Если процесс превышает время ожидания или имеет ненулевой код завершения, этот метод выбросит исключение. Объект Error будет содержать весь результат из child_process.spawnSync().
Никогда не передавайте несанизированные данные пользователя в эту функцию. Любые данные, содержащие символы командной строки, могут быть использованы для запуска произвольных команд.
child_process.spawnSync(command[, args][, options])
-
command<string> Команда для выполнения. -
args<string[]> Список строковых аргументов. -
options<Object>-
cwd<string> | <URL> Текущий рабочий каталог дочернего процесса. -
input<string> | <Buffer> | <TypedArray> | <DataView> Значение, которое будет передано в stdin запущенному процессу. Еслиstdio[0]установлено в'pipe', это значение переопределитstdio[0]. -
argv0<string> Явно задаёт значениеargv[0], передаваемое дочернему процессу. Если не указано, оно будет установлено вcommand. -
stdio<string> | <Array> Конфигурация stdio дочернего процесса. См.child_process.spawn()'sstdio. По умолчанию:'pipe'. -
env<Object> Параметры среды в формате ключ-значение. По умолчанию:process.env. -
uid<number> Устанавливает идентификатор пользователя процесса (см.setuid(2)). -
gid<number> Устанавливает идентификатор группы процесса (см.setgid(2)). -
timeout<number> Максимальное время выполнения процесса в миллисекундах. По умолчанию:undefined. -
killSignal<string> | <integer> Значение сигнала, используемого для завершения запущенного процесса. По умолчанию:'SIGTERM'. -
maxBuffer<number> Максимальный объём данных в байтах, разрешённый для stdout или stderr. При превышении этого значения дочерний процесс завершается, а вывод усекается. См. замечание вmaxBufferи Unicode. По умолчанию:1024 * 1024. -
encoding<string> Кодировка, используемая для всех входов и выходов stdio. По умолчанию:'buffer'. -
shell<boolean> | <string> Еслиtrue, запускаетcommandвнутри оболочки. Использует'/bin/sh'на Unix иprocess.env.ComSpecна Windows. Можно указать другую оболочку в виде строки. См. Требования к оболочке и По умолчанию оболочка Windows. По умолчанию:false(без оболочки). -
windowsVerbatimArguments<boolean> На Windows не происходит цитирование или экранирование аргументов. Игнорируется на Unix. Устанавливается автоматически вtrueпри указанииshellи CMD. По умолчанию:false. -
windowsHide<boolean> Скрыть окно консоли подпроцесса, которое обычно создаётся на системах Windows. По умолчанию:false.
-
- Возвращает: <Object>
-
pid<number> ИД дочернего процесса. -
output<Array> Массив результатов вывода stdio. -
stdout<Buffer> | <string> Содержимоеoutput[1]. -
stderr<Buffer> | <string> Содержимоеoutput[2]. -
status<number> | <null> Код завершения подпроцесса илиnull, если подпроцесс завершился из-за сигнала. -
signal<string> | <null> Используемый для завершения подпроцесса сигнал илиnull, если подпроцесс не завершился из-за сигнала. -
error<Error> Объект ошибки, если дочерний процесс завершился неудачно или истекло время ожидания.
-
Метод child_process.spawnSync() в целом идентичен методу child_process.spawn() с тем отличием, что функция не вернётся, пока дочерний процесс не закроется полностью. Когда истекает время ожидания и отправляется killSignal, функция не вернётся, пока процесс не завершится полностью. Если процесс перехватывает и обрабатывает сигнал SIGTERM, и не завершается, родительский процесс будет ожидать завершения дочернего процесса.
Если опция shell включена, не передавайте необработанный пользовательский ввод в эту функцию. Любой ввод, содержащий символы метаязыка оболочки, может быть использован для запуска произвольных команд.
Класс: ChildProcess
- Расширяет: <EventEmitter>
Экземпляры ChildProcess представляют запущенные дочерние процессы.
Экземпляры ChildProcess не предназначены для прямого создания. Вместо этого используйте методы child_process.spawn(), child_process.exec(), child_process.execFile() или child_process.fork() для создания экземпляров ChildProcess.
Событие: 'close'
-
code<число> Код завершения, если дочерний процесс завершился самостоятельно. -
signal<строка> Сигнал, по которому был завершен дочерний процесс.
Событие 'close' срабатывает после завершения процесса и закрытия потоков ввода-вывода дочернего процесса. Это отличается от события 'exit', так как несколько процессов могут использовать общие потоки ввода-вывода. Событие 'close' всегда срабатывает после события 'exit' или 'error', если дочерний процесс не был запущен.
const { spawn } = require('node:child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
});
ls.on('exit', (code) => {
console.log(`child process exited with code ${code}`);
}); copy Событие: 'disconnect'
Событие 'disconnect' срабатывает после вызова метода subprocess.disconnect() в родительском процессе или process.disconnect() в дочернем процессе. После разъединения отправка и получение сообщений больше невозможны, и свойство subprocess.connected устанавливается в false.
Событие: 'error'
-
err<Ошибка> Ошибка.
Событие 'error' срабатывает в следующих случаях:
- Процесс не может быть запущен.
- Процесс не может быть остановлен.
- Отправка сообщения дочернему процессу не удалась.
- Дочерний процесс был прерван с помощью опции
signal.
Событие 'exit' может или не может сработать после возникновения ошибки. При прослушивании событий 'exit' и 'error' следите за тем, чтобы обработчики функций не вызывались несколько раз.
См. также subprocess.kill() и subprocess.send().
Событие: 'exit'
-
code<число> Код завершения, если дочерний процесс завершился самостоятельно. -
signal<строка> Сигнал, по которому был завершен дочерний процесс.
Событие 'exit' срабатывает после завершения дочернего процесса. Если процесс завершился, code — это код завершения процесса, в противном случае null. Если процесс завершился из-за получения сигнала, signal — строковое имя сигнала, в противном случае null. Одно из двух значений всегда будет отличным от null.
Когда срабатывает событие 'exit', потоки ввода-вывода дочернего процесса могут быть еще открыты.
Node.js устанавливает обработчики сигналов для SIGINT и SIGTERM, и процессы Node.js не завершатся сразу же после получения этих сигналов. Вместо этого Node.js выполнит ряд действий по очистке, а затем повторно сгенерирует обработанный сигнал.
См. waitpid(2).
Событие: 'message'
-
message<Объект> Разбор объекта JSON или примитивного значения. -
sendHandle<Дескриптор> | <undefined>undefinedили объектnet.Socket,net.Serverилиdgram.Socket.
Событие 'message' срабатывает, когда дочерний процесс использует process.send() для отправки сообщений.
Сообщение проходит сериализацию и разбор. Результирующее сообщение может отличаться от исходного.
Если опция serialization была установлена в 'advanced' при запуске дочернего процесса, аргумент message может содержать данные, которые JSON не может представить. Подробнее см. Расширенная сериализация.
Событие: 'spawn'
Событие 'spawn' срабатывает, когда дочерний процесс успешно запущен. Если дочерний процесс не запущен успешно, событие 'spawn' не срабатывает, и вместо него срабатывает событие 'error'.
Если событие 'spawn' срабатывает, оно срабатывает раньше всех других событий и раньше получения любых данных через stdout или stderr.
Событие 'spawn' срабатывает независимо от того, возникает ли ошибка внутри запущенного процесса. Например, если bash some-command запущен успешно, событие 'spawn' сработает, хотя bash может не удаться запустить some-command. Это ограничение также относится к использованию { shell: true }.
subprocess.channel
- <Объект> Каналы связи с дочерним процессом.
Свойство subprocess.channel ссылается на канал связи с дочерним процессом. Если канал не существует, это свойство имеет значение undefined.
subprocess.channel.ref()
Этот метод заставляет канал связи поддерживать цикл обработки событий родительского процесса, если .unref() был вызван ранее.
subprocess.channel.unref()
Этот метод заставляет канал связи не поддерживать цикл обработки событий родительского процесса и позволяет завершить его, даже если канал открыт.
subprocess.connected
-
<логическое значение> Устанавливается в
falseпосле вызоваsubprocess.disconnect().
Свойство subprocess.connected указывает, возможно ли отправлять и получать сообщения от дочернего процесса. Когда subprocess.connected имеет значение false, отправка и получение сообщений больше невозможны.
subprocess.disconnect()
Закрывает канал связи между родительским и дочерним процессами, позволяя дочернему процессу выйти корректно, если нет других подключений, которые его поддерживают. После вызова этого метода свойства subprocess.connected и process.connected в родительском и дочернем процессах (соответственно) будут установлены в false, и передача сообщений между процессами больше невозможна.
Событие 'disconnect' будет сгенерировано, когда в процессе получения нет сообщений. Это обычно срабатывает сразу после вызова subprocess.disconnect().
Если дочерний процесс является экземпляром Node.js (например, запущен с помощью child_process.fork()), метод process.disconnect() можно вызвать в дочернем процессе для закрытия канала связи.
subprocess.exitCode
Свойство subprocess.exitCode указывает код завершения дочернего процесса. Если дочерний процесс все еще работает, поле будет равно null.
subprocess.kill([signal])
-
signal<число> | <строка> - Возвращает: <логическое значение>
Метод subprocess.kill() отправляет сигнал дочернему процессу. Если аргумент не указан, процессу будет отправлен сигнал 'SIGTERM'. Список доступных сигналов см. в signal(7). Функция возвращает true если kill(2) завершилась успешно, и false в противном случае.
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process.
grep.kill('SIGHUP'); copy Объект ChildProcess может генерировать событие 'error', если сигнал не может быть доставлен. Отправка сигнала дочернему процессу, который уже завершил работу, не является ошибкой, но может иметь непредвиденные последствия. В частности, если идентификатор процесса (PID) был повторно назначен другому процессу, сигнал будет доставлен этому процессу, что может привести к неожиданным результатам.
Хотя функция называется kill, сигнал, доставленный дочернему процессу, может не привести к фактическому завершению процесса.
Для справки обратитесь к kill(2).
В Windows, где POSIX-сигналы отсутствуют, аргумент signal будет проигнорирован, и процесс будет завершён жёстко и внезапно (аналогично 'SIGKILL'). Более подробную информацию см. в разделе События сигналов.
В Linux, дочерние процессы дочерних процессов не будут завершены при попытке убить их родителя. Это, вероятно, произойдёт при запуске нового процесса в оболочке или с использованием опции shell модуля ChildProcess:
'use strict';
const { spawn } = require('node:child_process');
const subprocess = spawn(
'sh',
[
'-c',
`node -e "setInterval(() => {
console.log(process.pid, 'is alive')
}, 500);"`,
], {
stdio: ['inherit', 'inherit', 'inherit'],
},
);
setTimeout(() => {
subprocess.kill(); // Does not terminate the Node.js process in the shell.
}, 2000); copy
subprocess[Symbol.dispose]()
Вызывает subprocess.kill() с 'SIGTERM'.
subprocess.killed
-
<логическое значение> Устанавливается в
trueпосле успешной отправки сигнала дочернему процессу с помощьюsubprocess.kill().
Свойство subprocess.killed указывает, успешно ли дочерний процесс получил сигнал от subprocess.kill(). Свойство killed не означает, что дочерний процесс был завершён.
subprocess.pid
Возвращает идентификатор процесса (PID) дочернего процесса. Если дочерний процесс не удалось запустить из-за ошибок, значение будет undefined, и будет выведено событие error.
const { spawn } = require('node:child_process');
const grep = spawn('grep', ['ssh']);
console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end(); copy
subprocess.ref()
Вызов subprocess.ref() после вызова subprocess.unref() восстановит удалённый счётчик ссылок для дочернего процесса, заставив родителя дождаться завершения дочернего процесса перед собственным завершением.
const { spawn } = require('node:child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
});
subprocess.unref();
subprocess.ref(); copy
subprocess.send(message[, sendHandle[, options]][, callback])
-
message<Объект> -
sendHandle<Дескриптор> | <неопределено>undefined, или объектnet.Socket,net.Serverилиdgram.Socket. -
options<Объект> Аргументoptions, если он присутствует, представляет собой объект, используемый для параметризации отправки определённых типов дескрипторов.optionsподдерживает следующие свойства:-
keepOpen<логическое значение> Значение, которое может быть использовано при передаче экземпляровnet.Socket. Еслиtrue, сокет остается открытым в процессе отправки. По умолчанию:false.
-
-
callback<Функция> - Возвращает: <логическое значение>
Когда между родителем и дочерним процессом установлено IPC-соединение (например, при использовании child_process.fork()), метод subprocess.send() может использоваться для отправки сообщений дочернему процессу. Когда дочерний процесс является экземпляром Node.js, эти сообщения могут быть получены через событие 'message'.
Сообщение проходит сериализацию и парсинг. Результирующее сообщение может отличаться от исходного.
Например, в скрипте родителя:
const cp = require('node:child_process');
const n = cp.fork(`${__dirname}/sub.js`);
n.on('message', (m) => {
console.log('PARENT got message:', m);
});
// Causes the child to print: CHILD got message: { hello: 'world' }
n.send({ hello: 'world' }); copy А затем скрипт дочернего процесса, 'sub.js' может выглядеть так:
process.on('message', (m) => {
console.log('CHILD got message:', m);
});
// Causes the parent to print: PARENT got message: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN }); copy Дочерние процессы Node.js будут иметь собственный метод process.send(), позволяющий дочернему процессу отправлять сообщения родителю.
Существует особый случай при отправке сообщения {cmd: 'NODE_foo'}. Сообщения, содержащие префикс NODE_ в свойстве cmd предназначены для использования в ядре Node.js и не будут генерировать событие 'message' в дочернем процессе. Вместо этого такие сообщения генерируются с помощью события 'internalMessage' и потребляются внутри Node.js. Приложениям следует избегать использования таких сообщений или прослушивания событий 'internalMessage', так как они могут быть изменены без предварительного уведомления.
Необязательный аргумент sendHandle , который может быть передан в subprocess.send() предназначен для передачи объекта TCP-сервера или сокета дочернему процессу. Дочерний процесс получит объект в качестве второго аргумента, переданного в функцию обратного вызова, зарегистрированную для события 'message'. Любые данные, полученные и буферизованные в сокете, не будут отправлены дочернему процессу. Отправка IPC-сокетов не поддерживается в Windows.
Необязательный аргумент callback — функция, которая вызывается после отправки сообщения, но до получения его дочерним процессом. Функция вызывается с единственным аргументом: null при успехе или объектом Error при ошибке.
Если функция callback не указана и сообщение не может быть отправлено, объект ChildProcess сгенерирует событие 'error'. Это может произойти, например, если дочерний процесс уже завершён.
subprocess.send() вернёт false , если канал закрыт или количество неопосланных сообщений превышает порог, при котором отправка дополнительных сообщений нецелесообразна. В противном случае метод возвращает true. Функцию callback можно использовать для реализации управления потоком.
Пример: отправка объекта сервера
Аргумент sendHandle может использоваться, например, для передачи дескриптора объекта TCP-сервера дочернему процессу, как показано в примере ниже:
const subprocess = require('node:child_process').fork('subprocess.js');
// Open up the server object and send the handle.
const server = require('node:net').createServer();
server.on('connection', (socket) => {
socket.end('handled by parent');
});
server.listen(1337, () => {
subprocess.send('server', server);
}); copy Дочерний процесс получит объект сервера как:
process.on('message', (m, server) => {
if (m === 'server') {
server.on('connection', (socket) => {
socket.end('handled by child');
});
}
}); copy После того, как сервер теперь доступен родительскому и дочернему процессу, некоторые подключения могут обрабатываться родителем, а некоторые - дочерним процессом.
Хотя в примере выше используется сервер, созданный с помощью модуля node:net , серверы модуля node:dgram используют точно такой же рабочий процесс, за исключением прослушивания события 'message' вместо 'connection' и использования server.bind() вместо server.listen(). Однако это поддерживается только на платформах Unix.
Пример: отправка объекта сокета
Аналогично, аргумент sendHandler может быть использован для передачи дескриптора сокета дочернему процессу. Приведенный ниже пример запускает два дочерних процесса, каждый из которых обрабатывает подключения с "нормальным" или "специальным" приоритетом:
const { fork } = require('node:child_process');
const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);
// Open up the server and send sockets to child. Use pauseOnConnect to prevent
// the sockets from being read before they are sent to the child process.
const server = require('node:net').createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {
// If this is special priority...
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket);
return;
}
// This is normal priority.
normal.send('socket', socket);
});
server.listen(1337); copy Дочерний процесс получит дескриптор сокета как второй аргумент, переданный в функцию обратного вызова события:
process.on('message', (m, socket) => {
if (m === 'socket') {
if (socket) {
// Check that the client socket exists.
// It is possible for the socket to be closed between the time it is
// sent and the time it is received in the child process.
socket.end(`Request handled with ${process.argv[2]} priority`);
}
}
}); copy Не используйте .maxConnections с сокетом, переданным в подпроцесс. Родитель не может отслеживать, когда сокет уничтожается.
Любые обработчики 'message' в подпроцессе должны проверять существование socket , так как соединение может быть закрыто за время, необходимое для передачи соединения дочернему процессу.
subprocess.signalCode
Свойство subprocess.signalCode указывает на полученный дочерним процессом сигнал, если таковой был, в противном случае null.
subprocess.spawnargs
Свойство subprocess.spawnargs представляет собой полный список аргументов командной строки, с которыми был запущен дочерний процесс.
subprocess.spawnfile
Свойство subprocess.spawnfile указывает имя исполняемого файла дочернего процесса, который запускается.
Для child_process.fork(), его значение будет равно process.execPath. Для child_process.spawn(), его значение будет именем исполняемого файла. Для child_process.exec(), его значение будет именем оболочки, в которой запускается дочерний процесс.
subprocess.stderr
Поток, представляющий стандартный поток ошибок дочернего процесса.
Если дочерний процесс был запущен с параметром stdio[2] отличным от 'pipe', то этот поток будет null.
subprocess.stderr является псевдонимом для subprocess.stdio[2]. Обе свойства будут ссылаться на одно и то же значение.
Свойство subprocess.stderr может быть null или undefined если дочерний процесс не удалось запустить.
subprocess.stdin
Поток, представляющий стандартный поток ввода дочернего процесса.
Если дочерний процесс ожидает чтения всего входного потока, он не будет продолжен до тех пор, пока этот поток не будет закрыт с помощью end().
Если дочерний процесс был запущен с параметром stdio[0] отличным от 'pipe', то этот поток будет null.
subprocess.stdin является псевдонимом для subprocess.stdio[0]. Обе свойства будут ссылаться на одно и то же значение.
Свойство subprocess.stdin может быть null или undefined если дочерний процесс не удалось запустить.
subprocess.stdio
Разреженный массив каналов связи с дочерним процессом, соответствующий позициям в опции stdio, переданной в child_process.spawn(), которые были установлены в значение 'pipe'. subprocess.stdio[0], subprocess.stdio[1], и subprocess.stdio[2] также доступны как subprocess.stdin, subprocess.stdout, и subprocess.stderr, соответственно.
В следующем примере только fd 1 (stdout) дочернего процесса настроен как канал связи, поэтому только subprocess.stdio[1] родительского процесса является потоком, все остальные значения в массиве — null.
const assert = require('node:assert');
const fs = require('node:fs');
const child_process = require('node:child_process');
const subprocess = child_process.spawn('ls', {
stdio: [
0, // Use parent's stdin for child.
'pipe', // Pipe child's stdout to parent.
fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
],
});
assert.strictEqual(subprocess.stdio[0], null);
assert.strictEqual(subprocess.stdio[0], subprocess.stdin);
assert(subprocess.stdout);
assert.strictEqual(subprocess.stdio[1], subprocess.stdout);
assert.strictEqual(subprocess.stdio[2], null);
assert.strictEqual(subprocess.stdio[2], subprocess.stderr); copy Свойство subprocess.stdio может быть undefined если дочерний процесс не удалось запустить.
subprocess.stdout
Поток, представляющий стандартный поток вывода дочернего процесса.
Если дочерний процесс был запущен с параметром stdio[1] отличным от 'pipe', то этот поток будет null.
subprocess.stdout является псевдонимом для subprocess.stdio[1]. Обе свойства будут ссылаться на одно и то же значение.
const { spawn } = require('node:child_process');
const subprocess = spawn('ls');
subprocess.stdout.on('data', (data) => {
console.log(`Received chunk ${data}`);
}); copy Свойство subprocess.stdout может быть null или undefined если дочерний процесс не удалось запустить.
subprocess.unref()
По умолчанию родительский процесс ожидает завершения отсоединённого дочернего процесса. Чтобы предотвратить ожидание родительским процессом завершения данного subprocess, используйте метод subprocess.unref(). Это заставит цикл событий родительского процесса не включать дочерний процесс в счётчик ссылок, что позволит родительскому процессу завершиться независимо от дочернего, если нет установленного канала IPC между дочерним и родительским процессами.
const { spawn } = require('node:child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore',
});
subprocess.unref(); copy
maxBuffer и Unicode
Параметр maxBuffer задаёт максимальное количество байтов, разрешённых для stdout или stderr. Если это значение превышено, дочерний процесс завершается. Это влияет на вывод, включающий многобайтовые кодировки символов, такие как UTF-8 или UTF-16. Например, console.log('中文测试') отправит 13 байтов в кодировке UTF-8 в stdout, хотя символов всего 4.
Требования к оболочке
Оболочка должна понимать переключатель -c. Если оболочка 'cmd.exe', она должна понимать переключатели /d /s /c и разбор командной строки должен быть совместим.
По умолчанию оболочка Windows
Хотя Microsoft указывает, что %COMSPEC% должен содержать путь к 'cmd.exe' в корневой среде, дочерние процессы не всегда подчиняются этому требованию. Таким образом, в функциях child_process, где может быть запущена оболочка, используется 'cmd.exe' в качестве резервного варианта, если process.env.ComSpec недоступен.
Расширенная сериализация
Дочерние процессы поддерживают механизм сериализации для IPC, основанный на API сериализации модуля node:v8, основанном на алгоритме структурированного клонирования HTML. Он, как правило, более мощный и поддерживает больше встроенных типов JavaScript-объектов, таких как BigInt, Map и Set, ArrayBuffer и TypedArray, Buffer, Error, RegExp и т. д.
Однако, этот формат не является полным супермножеством JSON, и, например, свойства, заданные на объектах таких встроенных типов, не будут переданы через сериализацию. Кроме того, производительность может не быть эквивалентна производительности JSON, в зависимости от структуры передаваемых данных. Поэтому эта функция требует включения, установив параметр serialization в значение 'advanced' при вызове child_process.spawn() или child_process.fork().
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/api/child_process.html