Spec-Zone.ru › Node.js 6 LTS

Процесс-потомок

Устойчивость: 2 - Стабильно

Модуль child_process предоставляет возможность запуска процессов-потомков, аналогичным, но не идентичным, поведению popen(3). Эта возможность, в основном, обеспечивается функцией child_process.spawn():

const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

По умолчанию, каналы для stdin, stdout и stderr устанавливаются между родительским процессом Node.js и запущенным потомком. Можно передавать данные через эти каналы асинхронно. Обратите внимание, что некоторые программы используют построчную буферизацию ввода-вывода. Это не влияет на Node.js, но может означать, что данные, отправленные дочернему процессу, могут не быть немедленно обработаны.

Метод child_process.spawn() запускает дочерний процесс асинхронно, не блокируя цикл событий Node.js. Функция child_process.spawnSync() предоставляет эквивалентную функциональность синхронным способом, блокируя цикл событий, пока запущенный процесс не завершится или не будет прерван.

Для удобства, модуль 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. Эти объекты реализуют API Node.js EventEmitter, позволяя родительскому процессу регистрировать обработчики событий, которые вызываются при наступлении определенных событий в течение жизненного цикла дочернего процесса.

Методы child_process.exec() и child_process.execFile() дополнительно позволяют указать необязательную функцию callback, которая вызывается при завершении дочернего процесса.

Запуск файлов .bat и .cmd в Windows

Значение различия между child_process.exec() и child_process.execFile() может изменяться в зависимости от платформы. В операционных системах типа Unix (Unix, Linux, macOS) child_process.execFile() может быть более эффективным, потому что не запускает оболочку. Однако в Windows файлы .bat и .cmd не являются исполняемыми сами по себе без терминала и, следовательно, не могут быть запущены с помощью child_process.execFile(). При работе в Windows файлы .bat и .cmd можно вызывать с помощью child_process.spawn() с опцией shell, child_process.exec() или путем запуска cmd.exe и передачи файла .bat или .cmd в качестве аргумента (что делают опция shell и child_process.exec()). В любом случае, если имя файла скрипта содержит пробелы, его необходимо заключить в кавычки.

// On Windows Only ...
const spawn = require('child_process').spawn;
const bat = spawn('cmd.exe', ['/c', 'my.bat']);

bat.stdout.on('data', (data) => {
  console.log(data.toString());
});

bat.stderr.on('data', (data) => {
  console.log(data.toString());
});

bat.on('exit', (code) => {
  console.log(`Child exited with code ${code}`);
});
// OR...
const exec = require('child_process').exec;
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) => {
  // ...
});

child_process.exec(command[, options][, callback])

Добавлен в: v0.1.90
  • command <строка> Команда для запуска со значениями аргументов, разделенными пробелами.
  • options <Объект>
    • cwd <строка> Текущая рабочая директория дочернего процесса.
    • env <Объект> Параметры окружения в формате ключ-значение.
    • encoding <строка> По умолчанию: 'utf8'
    • shell <строка> Оболочка для выполнения команды. По умолчанию: '/bin/sh' в UNIX, 'cmd.exe' в Windows. Оболочка должна понимать переключатель -c в UNIX или /s /c в Windows. В Windows синтаксический анализ командной строки должен быть совместим с cmd.exe.
    • timeout <число> По умолчанию: 0
    • maxBuffer <число> Максимальный объем данных (в байтах) на stdout или stderr - при превышении лимита дочерний процесс убивается. По умолчанию: 200 * 1024.
    • killSignal <строка> | <целое> По умолчанию: 'SIGTERM'
    • uid <число> Устанавливает идентичность пользователя процесса (см. setuid(2)).
    • gid <число> Устанавливает идентичность группы процесса (см. setgid(2)).
  • callback <Функция> Вызывается с выводом при завершении процесса.
    • error <Ошибка>
    • stdout <строка> | <Буфер>
    • stderr <строка> | <Буфер>
  • Возвращает: <Процесс-потомок>

Запускает оболочку, а затем выполняет command в этой оболочке, буферизируя любой сгенерированный вывод.

Примечание: Никогда не передавайте необработанные данные пользователя в эту функцию. Любой ввод, содержащий метасимволы оболочки, может использоваться для запуска произвольных команд.

const exec = require('child_process').exec;
exec('cat *.js bad_file | wc -l', (error, stdout, stderr) => {
  if (error) {
    console.error(`exec error: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.log(`stderr: ${stderr}`);
});

Если функция callback предоставлена, она вызывается с аргументами (error, stdout, stderr). При успехе, error будет null. При ошибке, error будет экземпляром Error. Свойство error.code будет кодом завершения дочернего процесса, а error.signal будет установлено в сигнал, прервавший процесс. Любой код завершения, отличный от 0, считается ошибкой.

Аргументы stdout и stderr, передаваемые в обратный вызов, будут содержать вывод stdout и stderr дочернего процесса. По умолчанию Node.js будет декодировать вывод как UTF-8 и передавать строки в обратный вызов. Опция encoding может быть использована для указания кодировки символов, используемой для декодирования вывода stdout и stderr. Если encoding равно 'buffer', или это неподдерживаемая кодировка символов, в обратный вызов вместо этого будут переданы объекты Buffer.

Аргумент options может быть передан в качестве второго аргумента для настройки способа запуска процесса. Значения по умолчанию:

const defaults = {
  encoding: 'utf8',
  timeout: 0,
  maxBuffer: 200 * 1024,
  killSignal: 'SIGTERM',
  cwd: null,
  env: null
};

Если timeout больше 0, родительский процесс отправит сигнал, идентифицируемый свойством killSignal (по умолчанию 'SIGTERM'), если дочерний процесс будет выполняться дольше timeout миллисекунд.

Примечание: в отличие от системного вызова exec(3) POSIX, child_process.exec() не заменяет существующий процесс и использует оболочку для выполнения команды.

child_process.execFile(file[, args][, options][, callback])

Добавлена в: v0.1.91
  • file <строка> Имя или путь к исполняемому файлу для запуска.
  • args <массив строк> Список строковых аргументов.
  • options <объект>
    • cwd <строка> Текущий рабочий каталог дочернего процесса.
    • env <объект> Параметры окружения в формате ключ-значение.
    • encoding <строка> По умолчанию: 'utf8'
    • timeout <число> По умолчанию: 0
    • maxBuffer <число> Максимальный объем данных (в байтах) для stdout или stderr - превышение приведет к завершению дочернего процесса. По умолчанию: 200 * 1024.
    • killSignal <строка> | <целое число> По умолчанию: 'SIGTERM'
    • uid <число> Устанавливает идентификатор пользователя процесса (см. setuid(2)).
    • gid <число> Устанавливает идентификатор группы процесса (см. setgid(2)).
  • callback <функция> Вызывается с выводом при завершении процесса.
    • error <ошибка>
    • stdout <строка> | <Буфер>
    • stderr <строка> | <Буфер>
  • Возвращает: <Дочерний процесс>

Функция child_process.execFile() похожа на child_process.exec(), за исключением того, что она не запускает оболочку. Вместо этого указанный исполняемый файл file запускается напрямую как новый процесс, что немного эффективнее, чем child_process.exec().

Поддерживаются те же опции, что и для child_process.exec(). Поскольку оболочка не запускается, такие действия, как перенаправление ввода-вывода и обработка шаблонов файлов, не поддерживаются.

const execFile = require('child_process').execFile;
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    throw error;
  }
  console.log(stdout);
});

Аргументы stdout и stderr, передаваемые в обратный вызов, будут содержать вывод stdout и stderr дочернего процесса. По умолчанию Node.js будет декодировать вывод как UTF-8 и передавать строки в обратный вызов. Опция encoding может быть использована для указания кодировки символов, используемой для декодирования вывода stdout и stderr. Если encoding равно 'buffer', или это неподдерживаемая кодировка символов, в обратный вызов вместо этого будут переданы объекты Buffer.

child_process.fork(modulePath[, args][, options])

Добавлена в: v0.5.0
  • modulePath <строка> Модуль для запуска в дочернем процессе.
  • args <массив> Список строковых аргументов.
  • options <объект>
    • cwd <строка> Текущий рабочий каталог дочернего процесса.
    • env <объект> Параметры окружения в формате ключ-значение.
    • execPath <строка> Исполняемый файл, используемый для создания дочернего процесса.
    • execArgv <массив> Список строковых аргументов, передаваемых исполняемому файлу. По умолчанию: process.execArgv
    • silent <булево значение> Если true, stdin, stdout и stderr дочернего процесса будут переданы родителю, в противном случае они будут унаследованы от родителя. См. опции 'pipe' и 'inherit' для child_process.spawn() и stdio для дополнительных деталей. По умолчанию: false
    • stdio <массив> Поддерживает массивовый вариант опции child_process.spawn() stdio. При указании этой опции она переопределяет silent. Массив должен содержать ровно один элемент со значением 'ipc', в противном случае будет выброшено исключение. Например, [0, 1, 2, 'ipc'].
    • uid <число> Устанавливает идентификатор пользователя процесса (см. setuid(2)).
    • gid <число> Устанавливает идентификатор группы процесса (см. setgid(2)).
  • Возвращает: <Дочерний процесс>

Метод 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 в дочернем процессе. Ввод и вывод в этом fd ожидаются в виде объектов JSON, разделенных по строкам.

Примечание: в отличие от системного вызова fork(2) POSIX, child_process.fork() не клонирует текущий процесс.

END_OF_DOCUMENT_MARKER

Примечание: опция shell доступная в child_process.spawn() не поддерживается child_process.fork() и будет проигнорирована, если задана.

child_process.spawn(command[, args][, options])

Добавлен в: v0.1.90
  • command <строка> Команда для выполнения.
  • args <Массив> Список строковых аргументов.
  • options <Объект>
    • cwd <строка> Текущий рабочий каталог дочернего процесса.
    • env <Объект> Параметры окружения в формате ключ-значение.
    • argv0 <строка> Явно заданное значение argv[0] передаваемое дочернему процессу. Будет установлено в значение command, если не указано.
    • stdio <Массив> | <строка> Конфигурация stdio дочернего процесса (см. options.stdio).
    • detached <логическое значение> Подготовка дочернего процесса к независимому запуску от родительского. Конкретное поведение зависит от платформы, см. options.detached).
    • uid <число> Установка идентификатора пользователя процесса (см. setuid(2)).
    • gid <число> Установка идентификатора группы процесса (см. setgid(2)).
    • shell <логическое значение> | <строка> Если true, запускает command внутри оболочки. Использует '/bin/sh' на UNIX и 'cmd.exe' на Windows. Можно указать другую оболочку как строку. Оболочка должна понимать переключатель -c на UNIX или /s /c на Windows. По умолчанию: false (без оболочки).
  • Возвращает: <Дочерний процесс>

Метод child_process.spawn() запускает новый процесс, используя заданные command, с аргументами командной строки в args. Если опущено, args по умолчанию устанавливается в пустой массив.

Примечание: Если опция shell включена, не передавайте несанизированные данные пользователя в эту функцию. Любые входные данные, содержащие метасимволы оболочки, могут быть использованы для запуска произвольных команд.

Третий аргумент может быть использован для задания дополнительных опций, со следующими значениями по умолчанию:

const defaults = {
  cwd: undefined,
  env: process.env
};

Используйте cwd для задания рабочего каталога, из которого запускается процесс. Если не указано, используется текущий рабочий каталог.

Используйте env для задания переменных среды, которые будут доступны новому процессу. По умолчанию используется process.env.

Пример запуска ls -lh /usr, захвата stdout, stderr, и кода завершения:

const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

Пример: Очень сложный способ запуска ps ax | grep ssh

const spawn = require('child_process').spawn;
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.log(`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.log(`grep stderr: ${data}`);
});

grep.on('close', (code) => {
  if (code !== 0) {
    console.log(`grep process exited with code ${code}`);
  }
});

Пример проверки на ошибки spawn:

const spawn = require('child_process').spawn;
const subprocess = spawn('bad_command');

subprocess.on('error', (err) => {
  console.log('Failed to start subprocess.');
});

Примечание: Некоторые платформы (macOS, Linux) будут использовать значение argv[0] для заголовка процесса, в то время как другие (Windows, SunOS) будут использовать command.

Примечание: Node.js в настоящее время перезаписывает argv[0] с process.execPath при запуске, поэтому process.argv[0] в дочернем процессе Node.js не будет совпадать с параметром argv0 переданным в spawn из родительского процесса. Восстановите его с помощью свойства process.argv0 вместо этого.

options.detached

Добавлен в: v0.7.10

На Windows, установка options.detached в true позволяет дочернему процессу продолжать работу после завершения родительского. Дочерний процесс будет иметь собственное окно консоли. После активации для дочернего процесса, его нельзя отключить.

На платформах, отличных от Windows, если options.detached установлено в true, дочерний процесс станет лидером новой группы процессов и сеанса. Обратите внимание, что дочерние процессы могут продолжать выполняться после завершения родительского, независимо от того, отделены они или нет. Подробнее см. setsid(2).

По умолчанию родительский процесс будет ждать завершения отделённого дочернего процесса. Чтобы предотвратить ожидание родительского процесса для данного subprocess, используйте метод subprocess.unref(). Это заставит цикл событий родителя не включать дочерний процесс в свой счетчик ссылок, позволяя родительскому процессу завершиться независимо от дочернего, если между ними нет установленного канала IPC.

При использовании опции detached для запуска долгоживущего процесса, процесс не будет оставаться в фоновом режиме после завершения родителя, если ему не предоставлена конфигурация stdio, которая не подключена к родителю. Если родительский stdio унаследован, дочерний процесс останется подключенным к управляющему терминалу.

Пример долгоживущего процесса, путем отделения и также игнорирования его родительских дескрипторов файлов stdio, чтобы игнорировать завершение родительского процесса:

const spawn = require('child_process').spawn;

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore'
});

subprocess.unref();

В качестве альтернативы, можно перенаправить вывод дочернего процесса в файлы:

const fs = require('fs');
const spawn = require('child_process').spawn;
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();

options.stdio

Добавлен в: v0.7.10

Опция options.stdio используется для настройки каналов, которые устанавливаются между родительским и дочерним процессами. По умолчанию stdin, stdout и stderr дочернего процесса перенаправляются в соответствующие потоки subprocess.stdin, subprocess.stdout и subprocess.stderr объекта ChildProcess. Это эквивалентно установке options.stdio в ['pipe', 'pipe', 'pipe'].

Для удобства options.stdio может быть одной из следующих строк:

  • 'pipe' - эквивалентно ['pipe', 'pipe', 'pipe'] (по умолчанию)
  • 'ignore' - эквивалентно ['ignore', 'ignore', 'ignore']
  • 'inherit' - эквивалентно [process.stdin, process.stdout, process.stderr] или [0,1,2]

В противном случае значение options.stdio - это массив, где каждый индекс соответствует fd в дочернем процессе. Fd 0, 1 и 2 соответствуют stdin, stdout и stderr соответственно. Дополнительные fd могут быть заданы для создания дополнительных каналов между родительским и дочерним процессами. Значение может быть одним из следующих:

  1. 'pipe' - Создаёт канал между дочерним процессом и родительским. Конец канала для родительского процесса доступен в родительском процессе в виде свойства объекта child_process как subprocess.stdio[fd]. Каналы, созданные для fd 0-2, также доступны как subprocess.stdin, subprocess.stdout и subprocess.stderr соответственно.
  2. 'ipc' - Создаёт канал IPC для обмена сообщениями/дескрипторами файлов между родительским и дочерним процессом. Дочерний процесс может иметь не более одного дескриптора IPC stdio. Установка этой опции включает метод subprocess.send(). Если дочерний процесс записывает JSON-сообщения в этот дескриптор файла, обработчик события subprocess.on('message') будет вызван в родительском процессе. Если дочерний процесс — это Node.js процесс, наличие канала IPC включит process.send(), process.disconnect(), process.on('disconnect') и process.on('message') в дочернем процессе.
  3. 'ignore' - Инструктирует Node.js игнорировать fd в дочернем процессе. Хотя Node.js всегда открывает fd 0-2 для запускаемых процессов, установка fd в 'ignore' заставит Node.js открыть /dev/null и подключить его к fd дочернего процесса.
  4. <Поток> объект - Поделиться потоком чтения или записи, который ссылается на tty, файл, сокет или канал с дочерним процессом. Дескриптор файла потока дублируется в дочернем процессе на fd, соответствующий индексу в массиве stdio. Обратите внимание, что поток должен иметь базовый дескриптор (потоки файлов не имеют его, пока не произойдёт событие 'open').
  5. Положительное целое число - Целое значение интерпретируется как дескриптор файла, который в настоящее время открыт в родительском процессе. Он делится с дочерним процессом, аналогично тому, как могут быть разделены объекты <Поток>.
  6. null, undefined - Использовать значение по умолчанию. Для stdio fd 0, 1 и 2 (то есть stdin, stdout и stderr) создаётся канал. Для fd 3 и выше, по умолчанию используется 'ignore'.

Пример:

const spawn = require('child_process').spawn;

// 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'] });

Стоит отметить, что при установлении канала IPC между родительским и дочерним процессами, и если дочерний процесс — это процесс Node.js, дочерний процесс запускается с неинициализированным каналом IPC (используя unref()) до тех пор, пока дочерний процесс не зарегистрирует обработчик события process.on('disconnect') или process.on('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])

Добавлен в: v0.11.12
  • file <строка> Имя или путь к исполняемому файлу для запуска.
  • args <массив строк> Список строковых аргументов.
  • options <Объект>
    • cwd <строка> Текущий рабочий каталог дочернего процесса.
    • input <строка> | <Буфер> Значение, которое будет передано как stdin дочернему процессу.
      • предоставление этого значения переопределит stdio[0]
    • stdio <строка> | <Массив> Настройка stdio дочернего процесса. По умолчанию: 'pipe'
      • stderr по умолчанию будет выводиться в stderr родительского процесса, если не указано stdio
    • env <Объект> Параметры окружения в формате ключ-значение.
    • uid <число> Устанавливает идентификатор пользователя процесса (см. setuid(2)).
    • gid <число> Устанавливает идентификатор группы процесса (см. setgid(2)).
    • timeout <число> Максимальное время работы процесса в миллисекундах. По умолчанию: undefined
    • killSignal <строка> | <целое число> Значение сигнала, используемого для завершения дочернего процесса. По умолчанию: 'SIGTERM'
    • maxBuffer <число> Максимальный объём данных (в байтах) для stdout или stderr — если превышен, дочерний процесс завершается.
    • encoding <строка> Кодировка, используемая для всех входов и выходов stdio. По умолчанию: 'buffer'
  • Возвращает: <Буфер> | <строка> stdout команды.

Метод child_process.execFileSync() в целом идентичен child_process.execFile() за исключением того, что он не вернётся, пока дочерний процесс не завершится полностью. При превышении таймаута и отправке сигнала killSignal, метод не вернётся, пока процесс не завершится полностью. Обратите внимание, что если дочерний процесс перехватывает и обрабатывает сигнал SIGTERM и не завершается, родительский процесс всё равно будет ждать завершения дочернего процесса.

Если процесс превышает время ожидания или имеет ненулевой код выхода, этот метод выбросит исключение Error, которое будет содержать полный результат базового метода child_process.spawnSync().

child_process.execSync(command[, options])

Добавлен в: v0.11.12
  • command <строка> Команда для запуска.
  • options <Объект>
    • cwd <строка> Текущий рабочий каталог дочернего процесса.
    • input <строка> | <Буфер> Значение, которое будет передано как stdin дочернему процессу.
      • предоставление этого значения переопределит stdio[0]
    • stdio <строка> | <Массив> Настройка stdio дочернего процесса. По умолчанию: 'pipe'
      • stderr по умолчанию будет выводиться в stderr родительского процесса, если не указано stdio
    • env <Объект> Параметры окружения в формате ключ-значение.
    • shell <строка> Оболочка для выполнения команды. По умолчанию: '/bin/sh' на UNIX, 'cmd.exe' на Windows. Оболочка должна понимать переключатель -c на UNIX или /s /c на Windows. На Windows синтаксический анализ командной строки должен быть совместим с cmd.exe.
    • uid <число> Устанавливает идентификатор пользователя процесса. (см. setuid(2)).
    • gid <число> Устанавливает идентификатор группы процесса. (см. setgid(2)).
    • timeout <число> Максимальное время работы процесса в миллисекундах. По умолчанию: undefined
    • killSignal <строка> | <целое число> Значение сигнала для завершения дочернего процесса. По умолчанию: 'SIGTERM'
    • maxBuffer <число> Максимальный объём данных (в байтах) для stdout или stderr — если превышен, дочерний процесс завершается.
    • encoding <строка> Кодировка для всех входов и выходов stdio. По умолчанию: 'buffer'
  • Возвращает: <Буфер> | <строка> stdout команды.

Метод child_process.execSync() в целом идентичен child_process.exec() за исключением того, что он не вернётся, пока дочерний процесс не завершится полностью. При превышении таймаута и отправке сигнала killSignal, метод не вернётся, пока процесс не завершится полностью. Обратите внимание, что если дочерний процесс перехватывает и обрабатывает сигнал SIGTERM и не завершается, родительский процесс будет ждать завершения дочернего процесса.

END_OF_DOCUMENT_MARKER

Если процесс зависает или завершается с ненулевым кодом возврата, этот метод будет вызывать исключение. Объект Error будет содержать весь результат из child_process.spawnSync()

Примечание: никогда не передавайте необработанные данные пользователя в эту функцию. Любые данные, содержащие метасимволы оболочки, могут быть использованы для запуска произвольных команд.

child_process.spawnSync(command[, args][, options])

Добавлена в: v0.11.12
  • command <строка> Команда для выполнения.
  • args <Массив> Список строковых аргументов.
  • options <Объект>
    • cwd <строка> Текущий рабочий каталог дочернего процесса.
    • input <строка> | <Буфер> Значение, которое будет передано в качестве stdin дочернему процессу
      • передача этого значения переопределит stdio[0].
    • stdio <строка> | <Массив> Конфигурация stdio дочернего процесса.
    • env <Объект> Параметры окружения в формате ключ-значение.
    • uid <число> Устанавливает идентификатор пользователя процесса (см. setuid(2)).
    • gid <число> Устанавливает идентификатор группы процесса (см. setgid(2)).
    • timeout <число> Максимальное время выполнения процесса в миллисекундах. По умолчанию: undefined
    • killSignal <строка> | <целое число> Значение сигнала, используемого для завершения дочернего процесса. По умолчанию: 'SIGTERM'
    • maxBuffer <число> Максимальный объем данных (в байтах) на stdout или stderr – при превышении дочерний процесс завершается.
    • encoding <строка> Кодировка, используемая для всех входов и выходов stdio. По умолчанию: 'buffer'
    • shell <логическое значение> | <строка> Если true, запускает command внутри оболочки. Использует '/bin/sh' на UNIX и 'cmd.exe' на Windows. Другая оболочка может быть указана в виде строки. Оболочка должна понимать параметр -c на UNIX или /s /c на Windows. По умолчанию: false (без оболочки).
  • Возвращает: <Объект>
    • pid <число> Идентификатор дочернего процесса (PID).
    • output <Массив> Массив результатов вывода stdio.
    • stdout <Буфер> | <строка> Содержимое output[1].
    • stderr <Буфер> | <строка> Содержимое output[2].
    • status <число> Код возврата дочернего процесса.
    • signal <строка> Сигнал, используемый для завершения дочернего процесса.
    • error <Ошибка> Объект ошибки, если дочерний процесс завершился с ошибкой или по таймауту.

Метод child_process.spawnSync() в целом идентичен child_process.spawn() за исключением того, что функция не вернётся, пока дочерний процесс не закроется полностью. При возникновении таймаута и отправке сигнала killSignal, метод не вернётся, пока процесс не завершится полностью. Обратите внимание, что если процесс перехватывает и обрабатывает сигнал SIGTERM и не завершается, родительский процесс будет ждать завершения дочернего процесса.

Примечание: если опция shell включена, не передавайте необработанные данные пользователя в эту функцию. Любые данные, содержащие метасимволы оболочки, могут быть использованы для запуска произвольных команд.

Класс: ChildProcess

Добавлена в: v2.2.0

Экземпляры класса ChildProcess являются EventEmitters, представляющими запущенные дочерние процессы.

Экземпляры ChildProcess не предназначены для прямого создания. Вместо этого используйте методы child_process.spawn(), child_process.exec(), child_process.execFile() или child_process.fork() для создания экземпляров ChildProcess.

Событие: 'close'

Добавлена в: v0.7.7
  • code <число> Код возврата, если дочерний процесс завершился самостоятельно.
  • signal <строка> Сигнал, по которому был завершен дочерний процесс.

Событие 'close' генерируется, когда потоки stdio дочернего процесса закрыты. Это отличается от события 'exit', поскольку несколько процессов могут использовать одни и те же потоки stdio.

Событие: 'disconnect'

Добавлена в: v0.7.2

Событие 'disconnect' генерируется после вызова метода subprocess.disconnect() в родительском процессе или process.disconnect() в дочернем процессе. После отключения отправлять и получать сообщения больше нельзя, и свойство subprocess.connected становится false.

Событие: 'error'

  • err <Ошибка> Ошибка.

Событие 'error' генерируется в следующих случаях:

  1. Процесс не может быть запущен,
  2. Процесс не может быть завершен,
  3. Отправка сообщения дочернему процессу завершилась ошибкой.

Обратите внимание, что событие 'exit' может быть или не быть сгенерировано после возникновения ошибки. Если вы подписываетесь на события 'exit' и 'error', важно предотвратить случайное вызов обработчиков функций несколько раз.

См. также subprocess.kill() и subprocess.send().

Событие: 'exit'

Добавлена в: v0.1.90
  • code <число> Код возврата, если дочерний процесс завершился самостоятельно.
  • signal <строка> Сигнал, по которому был завершен дочерний процесс.

Событие 'exit' генерируется после завершения дочернего процесса. Если процесс завершился, code – это конечный код возврата процесса, иначе null. Если процесс завершился из-за получения сигнала, signal – это строковое имя сигнала, иначе null. Одно из двух значений всегда будет ненулевым.

Обратите внимание, что при возникновении события 'exit', потоки stdio дочернего процесса могут всё ещё быть открытыми.

END_OF_DOCUMENT_MARKER

Также обратите внимание, что Node.js устанавливает обработчики сигналов для SIGINT и SIGTERM, и процессы Node.js не завершатся немедленно из-за получения этих сигналов. Вместо этого Node.js выполнит последовательность действий по очистке, а затем повторно сгенерирует обработанный сигнал.

См. waitpid(2).

Событие: 'message'

Добавлен в: v0.5.9
  • message <Объект> Разбор JSON-объекта или примитивного значения.
  • sendHandle <Обработчик> Объект net.Socket или net.Server, или undefined.

Событие 'message' срабатывает, когда дочерний процесс использует process.send() для отправки сообщений.

subprocess.connected

Добавлен в: v0.7.2
  • <логическое значение> Устанавливается в false после вызова subprocess.disconnect().

Свойство subprocess.connected указывает, возможно ли посылать и получать сообщения от дочернего процесса. Когда subprocess.connected равно false, отправка и получение сообщений больше невозможны.

subprocess.disconnect()

Добавлен в: v0.7.2

Закрывает канал IPC между родительским и дочерним процессами, что позволяет дочернему процессу завершиться корректно, когда нет других соединений, поддерживающих его активность. После вызова этого метода свойства subprocess.connected и process.connected в родительском и дочернем процессе (соответственно) будут установлены в false, и обмен сообщениями между процессами будет больше невозможен.

Событие 'disconnect' будет выброшено, когда в процессе получения нет сообщений. Это чаще всего срабатывает сразу после вызова subprocess.disconnect().

Обратите внимание, что когда дочерний процесс является экземпляром Node.js (например, созданным с помощью child_process.fork()), метод process.disconnect() может быть вызван внутри дочернего процесса для закрытия канала IPC.

subprocess.kill([signal])

Добавлен в: v0.1.90
  • signal <строка>

Метод subprocess.kill() отправляет сигнал дочернему процессу. Если аргумент не указан, процессу будет отправлен сигнал 'SIGTERM'. Список доступных сигналов см. в signal(7).

const spawn = require('child_process').spawn;
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');

Объект ChildProcess может выбросить событие 'error', если сигнал не может быть доставлен. Отправка сигнала дочернему процессу, который уже завершился, не является ошибкой, но может иметь непредвиденные последствия. В частности, если идентификатор процесса (PID) был переназначен другому процессу, сигнал будет доставлен этому процессу вместо него, что может привести к неожиданным результатам.

Обратите внимание, что, хотя функция называется kill, сигнал, отправленный дочернему процессу, может не привести к фактическому завершению процесса.

См. kill(2) для справки.

Также обратите внимание: в Linux дочерние процессы дочерних процессов не будут завершены при попытке убить их родителя. Это, вероятно, произойдет при запуске нового процесса в оболочке или с использованием опции shell модуля ChildProcess, как показано в этом примере:

'use strict';
const spawn = require('child_process').spawn;

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 process in the shell
}, 2000);

subprocess.killed

Добавлен в: v0.5.10
  • <логическое значение> Устанавливается в true после успешного отправления сигнала дочернему процессу с помощью subprocess.kill().

Свойство subprocess.killed указывает, получил ли дочерний процесс сигнал от subprocess.kill(). Свойство killed не указывает, что дочерний процесс завершен.

subprocess.pid

Добавлен в: v0.1.90
  • <число> Целое число

Возвращает идентификатор процесса (PID) дочернего процесса.

Пример:

const spawn = require('child_process').spawn;
const grep = spawn('grep', ['ssh']);

console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end();

subprocess.send(message[, sendHandle[, options]][, callback])

Добавлен в: v0.5.9
  • message <Объект>
  • sendHandle <Обработчик>
  • options <Объект>
  • callback <Функция>
  • Возвращает: <логическое значение>

Когда между родительским и дочерним процессами установлен канал IPC (например, при использовании child_process.fork()), метод subprocess.send() может использоваться для отправки сообщений дочернему процессу. Если дочерний процесс — экземпляр Node.js, эти сообщения можно получить через событие process.on('message').

Например, в скрипте родительского процесса:

const cp = require('child_process');
const n = cp.fork(`${__dirname}/sub.js`);

n.on('message', (m) => {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

А затем скрипт дочернего процесса, 'sub.js' может выглядеть следующим образом:

process.on('message', (m) => {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

Дочерние процессы Node.js будут иметь собственный метод process.send(), позволяющий дочернему процессу отправлять сообщения обратно родителю.

Существует особый случай при отправке сообщения {cmd: 'NODE_foo'}. Сообщения, содержащие префикс NODE_ в свойстве cmd предназначены для использования внутри ядра Node.js и не будут выводиться в событии process.on('message') дочернего процесса. Вместо этого такие сообщения выводятся с помощью события process.on('internalMessage') и обрабатываются внутри Node.js. Приложениям следует избегать использования таких сообщений или прослушивания событий 'internalMessage' так как они могут быть изменены без предварительного уведомления.

Необязательный аргумент sendHandle, который может быть передан в subprocess.send(), используется для передачи объекта TCP-сервера или сокета дочернему процессу. Дочерний процесс получит объект в качестве второго аргумента, переданного в функцию обратного вызова, зарегистрированную в событии process.on('message'). Любые данные, полученные и буферизованные в сокете, не будут отправлены дочернему процессу.

Аргумент options, если он указан, представляет собой объект, используемый для параметризации отправки определенных типов обработчиков. options поддерживает следующие свойства:

  • keepOpen - Логическое значение, которое может использоваться при передаче экземпляров net.Socket. При true сокет остается открытым в процессе отправки. По умолчанию false.

Необязательный аргумент callback — это функция, вызываемая после отправки сообщения, но до того, как дочерний процесс его может получить. Функция вызывается с единственным аргументом: null при успехе или объектом Error при ошибке.

Если функция callback не указана, и сообщение не может быть отправлено, объект ChildProcess вызовет событие 'error'. Это может произойти, например, когда дочерний процесс уже завершился.

subprocess.send() вернёт false если канал закрыт или если количество неоправленных сообщений превышает порог, что делает нецелесообразным отправку ещё. В противном случае метод возвращает true. Функция callback может использоваться для реализации управления потоком.

Пример: отправка объекта сервера

Аргумент sendHandle может использоваться, например, для передачи обработчика объекта TCP-сервера дочернему процессу, как показано в примере ниже:

const subprocess = require('child_process').fork('subprocess.js');

// Open up the server object and send the handle.
const server = require('net').createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  subprocess.send('server', server);
});

Дочерний процесс затем получит объект сервера как:

process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', (socket) => {
      socket.end('handled by child');
    });
  }
});

После того как сервер будет разделен между родительским и дочерним процессом, некоторые соединения могут обрабатываться родителем, а некоторые — ребенком.

Хотя в примере выше используется сервер, созданный с помощью модуля net, серверы модуля dgram используют точно такой же рабочий процесс с исключениями: прослушивание на событии 'message' вместо 'connection' и использование server.bind() вместо server.listen(). Однако это в настоящее время поддерживается только на платформах UNIX.

Пример: отправка объекта сокета

Аналогично, аргумент sendHandler может использоваться для передачи обработчика сокета дочернему процессу. Пример ниже создаёт два дочерних процесса, каждый из которых обрабатывает соединения с приоритетом «обычный» или «специальный»:

const { fork } = require('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('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);

Дочерний процесс получит обработчик сокета как второй аргумент функции обратного вызова события:

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`);
    }
  }
});

После передачи сокета дочернему процессу родительский процесс больше не может отслеживать момент уничтожения сокета. Для обозначения этого свойство .connections становится null. Рекомендуется не использовать .maxConnections в этом случае.

Также рекомендуется, чтобы любые обработчики 'message' в дочернем процессе проверяли существование socket, так как соединение может быть закрыто за время, необходимое для отправки соединения дочернему процессу.

Примечание: эта функция использует JSON.stringify() для сериализации message.

subprocess.stderr

Добавлена в: v0.1.90
  • <stream.Readable>

Поток, представляющий стандартный вывод ошибок дочернего процесса.

Если дочерний процесс был запущен с stdio[2] отличным от 'pipe', то этот поток будет null.

subprocess.stderr — псевдоним для subprocess.stdio[2]. Обе свойства ссылаются на одно и то же значение.

subprocess.stdin

Добавлена в: v0.1.90
  • <stream.Writable>

Поток, представляющий стандартный ввод дочернего процесса.

Обратите внимание, что если дочерний процесс ждёт чтения всего ввода, он не продолжит работу до тех пор, пока этот поток не будет закрыт с помощью end().

Если дочерний процесс был запущен с stdio[0] отличным от 'pipe', то этот поток будет null.

subprocess.stdin — псевдоним для subprocess.stdio[0]. Обе свойства ссылаются на одно и то же значение.

subprocess.stdio

Добавлена в: v0.7.10
  • <Array>

Разряженный массив каналов связи с дочерним процессом, соответствующий позициям в параметре 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('assert');
const fs = require('fs');
const child_process = require('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);

subprocess.stdout

Добавлена в: v0.1.90
  • <stream.Readable>

Поток, представляющий стандартный вывод дочернего процесса.

Если дочерний процесс был запущен с stdio[1] отличным от 'pipe', то этот поток будет null.

subprocess.stdout — псевдоним для subprocess.stdio[1]. Обе свойства ссылаются на одно и то же значение.

maxBuffer и Юникод

Параметр maxBuffer определяет максимальное количество байтов, разрешённых в stdout или stderr. Если это значение превышено, дочерний процесс завершается. Это влияет на вывод, содержащий многобайтовые кодировки символов, такие как UTF-8 или UTF-16. Например, console.log('中文测试') отправит 13 байтов, закодированных в UTF-8, в stdout, хотя там только 4 символа.

© 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-v6.x/docs/api/child_process.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API