Процесс-потомок
Исходный код: 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.
В определенных случаях, таких как автоматизация скриптов оболочки, синхронные аналоги могут быть более удобными. Однако во многих случаях синхронные методы могут значительно повлиять на производительность из-за приостановки цикла событий, пока завершаются запущенные процессы.
Асинхронное создание процесса
Методы child_process.spawn(), child_process.fork(), child_process.exec() и child_process.execFile() следуют стандартной асинхронной модели программирования, характерной для других API Node.js.
Каждый из методов возвращает экземпляр ChildProcess. Эти объекты реализуют Node.js API 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 и stderr. Возвращённый экземпляр 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, stdin, stdout и stderr дочернего процесса будут направлены в родительский процесс, иначе они будут унаследованы от родительского, см. параметры'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 в дочернем процессе.
В отличие от системного вызова fork(2) POSIX, 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установлен для дескриптора. Это необходимо для перекрывающегося ввода-вывода ввода-вывода stdio дочернего процесса. Дополнительные сведения см. в документации. Это точно так же, как'pipe'на системах, отличных от Windows. -
'ipc': Создать канал IPC для передачи сообщений/файловых дескрипторов между родительским и дочерним процессами. УChildProcessможет быть не более одного файлового дескриптора IPC stdio. Установка этого параметра включает метод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': Передать соответствующий поток stdio в/из родительского процесса. В первых трёх позициях это эквивалентноprocess.stdin,process.stdout, иprocess.stderr, соответственно. В любой другой позиции — эквивалентно'ignore'. -
<Поток> объект: Поделиться потоком для чтения или записи, который ссылается на tty, файл, сокет или канал связи с дочерним процессом. Файловый дескриптор потока дублируется в дочернем процессе по fd, соответствующему индексу в массиве
stdio. Поток должен иметь базовый дескриптор (файловые потоки не начинаются до момента наступления события'open'). -
Положительное целое число: Целое значение интерпретируется как открытый файловый дескриптор в родительском процессе. Он разделяется с дочерним процессом, аналогично тому, как могут быть разделены объекты <Поток>. Передача сокетов не поддерживается в Windows.
-
null,undefined: Использовать значение по умолчанию. Для stdio fds 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<строка> | <Buffer> | <TypedArray> | <DataView> Значение, которое будет передано в stdin порождённого процесса. Еслиstdio[0]установлено в'pipe', это значение переопределитstdio[0]. -
stdio<строка> | <массив> Конфигурация stdio дочернего процесса. См.child_process.spawn()'sstdio. По умолчаниюstderrбудет выводиться на stderr родительского процесса, если не указанstdio. По умолчанию:'pipe'. -
env<объект> Параметры среды в формате ключ-значение. По умолчанию:process.env. -
uid<число> Устанавливает идентификатор пользователя процесса (см.setuid(2)). -
gid<число> Устанавливает идентификатор группы процесса (см.setgid(2)). -
timeout<число> Максимальное время выполнения процесса в миллисекундах. По умолчанию:undefined. -
killSignal<строка> | <целое> Значение сигнала для использования при завершении порождённого процесса. По умолчанию:'SIGTERM'. -
maxBuffer<число> Максимальный объём данных в байтах, разрешённый для stdout или stderr. При превышении порождённый процесс завершается. См. замечание вmaxBufferи Юникод. По умолчанию:1024 * 1024. -
encoding<строка> Кодировка, используемая для всех входов и выходов stdio. По умолчанию:'buffer'. -
windowsHide<логическое> Скрыть окно консоли дочернего процесса, которое обычно создаётся на системах Windows. По умолчанию:false. -
shell<логическое> | <строка> Еслиtrue, запускаетcommandвнутри оболочки. Использует'/bin/sh'на Unix иprocess.env.ComSpecна Windows. Можно указать другую оболочку в виде строки. См. Требования к оболочке и Стандартную оболочку Windows. По умолчанию:false(без оболочки).
-
- Возвращает: <Buffer> | <строка> Выход 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()поstdio. Значение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()иstdio. По умолчанию:'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и Юникод. По умолчанию: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
- <Объект> Канал IPC с дочерним процессом.
Свойство subprocess.channel — ссылка на канал IPC дочернего процесса. Если канал IPC отсутствует, свойство равно undefined.
subprocess.channel.ref()
Этот метод заставляет канал IPC поддерживать цикл событий родительского процесса, если .unref() был вызван ранее.
subprocess.channel.unref()
Этот метод заставляет канал IPC не поддерживать цикл событий родительского процесса и позволяет ему завершиться, даже когда канал открыт.
subprocess.connected
-
<булево> Устанавливается в
falseпосле вызоваsubprocess.disconnect().
Свойство subprocess.connected указывает, возможно ли отправлять и получать сообщения от дочернего процесса. Когда subprocess.connected равно false, отправлять или получать сообщения уже невозможно.
subprocess.disconnect()
Закрывает канал IPC между родительским и дочерним процессом, позволяя дочернему процессу завершиться корректно, если нет других подключений, которые его поддерживают. После вызова этого метода свойства subprocess.connected и process.connected в родительском и дочернем процессах (соответственно) будут установлены в false, и передача сообщений между процессами больше невозможна.
Событие 'disconnect' срабатывает, когда нет сообщений в процессе приема. Это чаще всего срабатывает сразу после вызова subprocess.disconnect().
Если дочерний процесс является экземпляром Node.js (например, запущен с помощью child_process.fork()), метод process.disconnect() можно вызвать в дочернем процессе для закрытия канала IPC.
subprocess.exitCode
Свойство subprocess.exitCode указывает код завершения дочернего процесса. Если дочерний процесс всё ещё работает, поле будет null.
subprocess.kill([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
-
<boolean> Устанавливается в
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 Процесс subprocess.js получит дескриптор сокета как второй аргумент функции обратного вызова события:
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 недоступен.
Расширенная сериализация
Дочерние процессы поддерживают механизм сериализации для межпроцессного взаимодействия, основанный на 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/dist/latest-v20.x/docs/api/child_process.html