Процесс-потомок
Исходный код: 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 По умолчанию, между родительским процессом Node.js и запущенным подпроцессом устанавливаются каналы для stdin, stdout, и stderr. Эти каналы имеют ограниченную (и зависящую от платформы) емкость. Если подпроцесс записывает в 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. Это необходимо для перекрывающего ввода-вывода (overlapped I/O) для дескрипторов stdio дочернего процесса. Более подробную информацию см. в документации. Это полностью аналогично'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: Использовать значение по умолчанию. Для 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.
В системах, подобных Unix, метод child_process.spawn() выполняет операции с памятью синхронно, прежде чем отделить цикл событий от дочернего процесса. Приложения с большим объёмом памяти могут столкнуться с проблемой производительности при частых вызовах child_process.spawn(). Более подробная информация доступна в V8 issue 7381.
См. также: 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]. -
stdio<строка> | <массив> Настройка 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 включена, не передавайте необработанные данные пользователя в эту функцию. Любой ввод, содержащий метасимволы оболочки, может быть использован для запуска произвольных команд.
child_process.execSync(command[, options])
-
command<string> Команда для выполнения. -
options<Object>-
cwd<string> | <URL> Текущий рабочий каталог дочернего процесса. -
input<string> | <Buffer> | <TypedArray> | <DataView> Значение, которое будет передано в stdin запущенному процессу. Предоставление этого значения переопределитstdio[0]. -
stdio<string> | <Array> Настройка 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]. -
argv0<string> Явное значениеargv[0], передаваемое дочернему процессу. Будет установлено вcommand, если не указано. -
stdio<string> | <Array> Настройка stdio дочернего процесса. -
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. Устанавливается автоматически, когдаshellзадан и равен CMD. По умолчанию:false. -
windowsHide<boolean> Скрыть окно консоли подпроцесса, которое обычно создаётся на системах Windows. По умолчанию:false.
-
- Возвращает: <Object>
-
pid<number> ИД дочернего процесса (PID). -
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<Дескриптор> Объектnet.Socketилиnet.Server, или undefined.
Событие 'message' срабатывает, когда дочерний процесс использует process.send() для отправки сообщений.
Сообщение проходит сериализацию и парсинг. Результирующее сообщение может отличаться от отправленного изначально.
Если параметр serialization был установлен в значение 'advanced' при запуске дочернего процесса, аргумент message может содержать данные, которые JSON не может представить. Подробнее см. Расширенная сериализация.
Событие: 'spawn'
Событие 'spawn' срабатывает, когда дочерний процесс успешно запущен. Если запуск дочернего процесса не удался, событие 'spawn' не срабатывает, а вместо него срабатывает событие 'error'.
Если событие срабатывает, оно происходит до всех других событий и до получения любых данных через stdout или stderr.
Событие 'spawn' сработает независимо от того, произошла ли ошибка внутри запущенного процесса. Например, если bash some-command запустится успешно, событие 'spawn' сработает, хотя bash может не удаться запустить some-command. Это ограничение также применяется при использовании { shell: true }.
subprocess.channel
- <Объект> Канальный сокет для межпроцессного взаимодействия с дочерним процессом.
Свойство 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])
-
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<Дескриптор> -
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'. Любые данные, которые были получены и буферизованы в сокете, не будут отправлены дочернему процессу.
Необязательная функция 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
Поток, представляющий процесс-потомка Readable Stream.
Если процесс-потомок был запущен с stdio[2] установленным в значение, отличное от 'pipe', то он будет null.
subprocess.stderr — псевдоним для subprocess.stdio[2]. Обе свойства ссылаются на одно и то же значение.
Свойство subprocess.stderr может принимать значение null или undefined, если процесс-потомок не был успешно запущен.
subprocess.stdin
Поток, представляющий стандартный ввод процесса-потомка Writable Stream.
Если процесс-потомок ожидает чтения всего своего ввода, он не продолжит выполнение до тех пор, пока этот поток не будет закрыт с помощью 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
Поток, представляющий стандартный вывод процесса-потомка Readable Stream.
Если процесс-потомок был запущен с 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 и Юникод
Параметр 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/dist/latest-v18.x/docs/api/child_process.html