mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
doc, child_process: add esm snippets
PR-URL: https://github.com/nodejs/node/pull/53616 Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
This commit is contained in:
1 parent
85b5ed5d41
commit
5e081a12b6
1 file changed
+491
-57
+491
-57
@@ -10,7 +10,7 @@ The `node:child_process` module provides the ability to spawn subprocesses in
|
||||
a manner that is similar, but not identical, to popen(3). This capability
|
||||
is primarily provided by the [`child_process.spawn()`][] function:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const ls = spawn('ls', ['-lh', '/usr']);
|
||||
|
||||
@@ -27,6 +27,23 @@ ls.on('close', (code) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from '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}`);
|
||||
});
|
||||
```
|
||||
|
||||
By default, pipes for `stdin`, `stdout`, and `stderr` are established between
|
||||
the parent Node.js process and the spawned subprocess. These pipes have
|
||||
limited (and platform-specific) capacity. If the subprocess writes to
|
||||
@@ -108,27 +125,30 @@ When running on Windows, `.bat` and `.cmd` files can be invoked using
|
||||
[`child_process.exec()`][] do). In any case, if the script filename contains
|
||||
spaces it needs to be quoted.
|
||||
|
||||
```js
|
||||
// On Windows Only...
|
||||
const { spawn } = require('node:child_process');
|
||||
const bat = spawn('cmd.exe', ['/c', 'my.bat']);
|
||||
```cjs
|
||||
// OR...
|
||||
const { exec, spawn } = require('node:child_process');
|
||||
|
||||
bat.stdout.on('data', (data) => {
|
||||
console.log(data.toString());
|
||||
exec('my.bat', (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
console.log(stdout);
|
||||
});
|
||||
|
||||
bat.stderr.on('data', (data) => {
|
||||
console.error(data.toString());
|
||||
});
|
||||
|
||||
bat.on('exit', (code) => {
|
||||
console.log(`Child exited with code ${code}`);
|
||||
// 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) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
```mjs
|
||||
// OR...
|
||||
const { exec, spawn } = require('node:child_process');
|
||||
import { exec, spawn } from 'node:child_process';
|
||||
|
||||
exec('my.bat', (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
@@ -197,7 +217,7 @@ directly by the shell and special characters (vary based on
|
||||
[shell](https://en.wikipedia.org/wiki/List_of_command-line_interpreters))
|
||||
need to be dealt with accordingly:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { exec } = require('node:child_process');
|
||||
|
||||
exec('"/path/to/test file/test.sh" arg1 arg2');
|
||||
@@ -208,6 +228,17 @@ exec('echo "The \\$HOME variable is $HOME"');
|
||||
// The $HOME variable is escaped in the first instance, but not in the second.
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { exec } from '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.
|
||||
```
|
||||
|
||||
**Never pass unsanitized user input to this function. Any input containing shell
|
||||
metacharacters may be used to trigger arbitrary command execution.**
|
||||
|
||||
@@ -225,7 +256,7 @@ can be used to specify the character encoding used to decode the stdout and
|
||||
stderr output. If `encoding` is `'buffer'`, or an unrecognized character
|
||||
encoding, `Buffer` objects will be passed to the callback instead.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { exec } = require('node:child_process');
|
||||
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
@@ -237,6 +268,18 @@ exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { exec } from '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}`);
|
||||
});
|
||||
```
|
||||
|
||||
If `timeout` is greater than `0`, the parent will send the signal
|
||||
identified by the `killSignal` property (the default is `'SIGTERM'`) if the
|
||||
child runs longer than `timeout` milliseconds.
|
||||
@@ -251,7 +294,7 @@ case of an error (including any error resulting in an exit code other than 0), a
|
||||
rejected promise is returned, with the same `error` object given in the
|
||||
callback, but with two additional properties `stdout` and `stderr`.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const util = require('node:util');
|
||||
const exec = util.promisify(require('node:child_process').exec);
|
||||
|
||||
@@ -263,11 +306,24 @@ async function lsExample() {
|
||||
lsExample();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { promisify } from 'node:util';
|
||||
import child_process from 'node:child_process';
|
||||
const exec = promisify(child_process.exec);
|
||||
|
||||
async function lsExample() {
|
||||
const { stdout, stderr } = await exec('ls');
|
||||
console.log('stdout:', stdout);
|
||||
console.error('stderr:', stderr);
|
||||
}
|
||||
lsExample();
|
||||
```
|
||||
|
||||
If the `signal` option is enabled, calling `.abort()` on the corresponding
|
||||
`AbortController` is similar to calling `.kill()` on the child process except
|
||||
the error passed to the callback will be an `AbortError`:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { exec } = require('node:child_process');
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
@@ -277,6 +333,16 @@ const child = exec('grep ssh', { signal }, (error) => {
|
||||
controller.abort();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { exec } from 'node:child_process';
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
const child = exec('grep ssh', { signal }, (error) => {
|
||||
console.error(error); // an AbortError
|
||||
});
|
||||
controller.abort();
|
||||
```
|
||||
|
||||
### `child_process.execFile(file[, args][, options][, callback])`
|
||||
|
||||
<!-- YAML
|
||||
@@ -337,7 +403,7 @@ The same options as [`child_process.exec()`][] are supported. Since a shell is
|
||||
not spawned, behaviors such as I/O redirection and file globbing are not
|
||||
supported.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { execFile } = require('node:child_process');
|
||||
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
@@ -347,6 +413,16 @@ const child = execFile('node', ['--version'], (error, stdout, stderr) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { execFile } from 'node:child_process';
|
||||
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
console.log(stdout);
|
||||
});
|
||||
```
|
||||
|
||||
The `stdout` and `stderr` arguments passed to the callback will contain the
|
||||
stdout and stderr output of the child process. By default, Node.js will decode
|
||||
the output as UTF-8 and pass strings to the callback. The `encoding` option
|
||||
@@ -361,7 +437,7 @@ case of an error (including any error resulting in an exit code other than 0), a
|
||||
rejected promise is returned, with the same `error` object given in the
|
||||
callback, but with two additional properties `stdout` and `stderr`.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const util = require('node:util');
|
||||
const execFile = util.promisify(require('node:child_process').execFile);
|
||||
async function getVersion() {
|
||||
@@ -371,6 +447,17 @@ async function getVersion() {
|
||||
getVersion();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { promisify } from 'node:util';
|
||||
import child_process from 'node:child_process';
|
||||
const execFile = promisify(child_process.execFile);
|
||||
async function getVersion() {
|
||||
const { stdout } = await execFile('node', ['--version']);
|
||||
console.log(stdout);
|
||||
}
|
||||
getVersion();
|
||||
```
|
||||
|
||||
**If the `shell` option is enabled, do not pass unsanitized user input to this
|
||||
function. Any input containing shell metacharacters may be used to trigger
|
||||
arbitrary command execution.**
|
||||
@@ -379,7 +466,7 @@ If the `signal` option is enabled, calling `.abort()` on the corresponding
|
||||
`AbortController` is similar to calling `.kill()` on the child process except
|
||||
the error passed to the callback will be an `AbortError`:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { execFile } = require('node:child_process');
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
@@ -389,6 +476,16 @@ const child = execFile('node', ['--version'], { signal }, (error) => {
|
||||
controller.abort();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { execFile } from 'node:child_process';
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
const child = execFile('node', ['--version'], { signal }, (error) => {
|
||||
console.error(error); // an AbortError
|
||||
});
|
||||
controller.abort();
|
||||
```
|
||||
|
||||
### `child_process.fork(modulePath[, args][, options])`
|
||||
|
||||
<!-- YAML
|
||||
@@ -500,13 +597,15 @@ If the `signal` option is enabled, calling `.abort()` on the corresponding
|
||||
`AbortController` is similar to calling `.kill()` on the child process except
|
||||
the error passed to the callback will be an `AbortError`:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { fork } = require('node:child_process');
|
||||
const process = require('node:process');
|
||||
|
||||
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 });
|
||||
@@ -517,6 +616,25 @@ if (process.argv[2] === 'child') {
|
||||
}
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { fork } from 'node:child_process';
|
||||
import process from 'node:process';
|
||||
|
||||
if (process.argv[2] === 'child') {
|
||||
setTimeout(() => {
|
||||
console.log(`Hello from ${process.argv[2]}!`);
|
||||
}, 1_000);
|
||||
} else {
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
const child = fork(import.meta.url, ['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
|
||||
}
|
||||
```
|
||||
|
||||
### `child_process.spawn(command[, args][, options])`
|
||||
|
||||
<!-- YAML
|
||||
@@ -624,7 +742,7 @@ process, the default is [`process.env`][].
|
||||
Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the
|
||||
exit code:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const ls = spawn('ls', ['-lh', '/usr']);
|
||||
|
||||
@@ -641,9 +759,26 @@ ls.on('close', (code) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from '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}`);
|
||||
});
|
||||
```
|
||||
|
||||
Example: A very elaborate way to run `ps ax | grep ssh`
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const ps = spawn('ps', ['ax']);
|
||||
const grep = spawn('grep', ['ssh']);
|
||||
@@ -678,9 +813,44 @@ grep.on('close', (code) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from '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}`);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Example of checking for failed `spawn`:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const subprocess = spawn('bad_command');
|
||||
|
||||
@@ -689,6 +859,15 @@ subprocess.on('error', (err) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from 'node:child_process';
|
||||
const subprocess = spawn('bad_command');
|
||||
|
||||
subprocess.on('error', (err) => {
|
||||
console.error('Failed to start subprocess.');
|
||||
});
|
||||
```
|
||||
|
||||
Certain platforms (macOS, Linux) will use the value of `argv[0]` for the process
|
||||
title while others (Windows, SunOS) will use `command`.
|
||||
|
||||
@@ -701,7 +880,7 @@ If the `signal` option is enabled, calling `.abort()` on the corresponding
|
||||
`AbortController` is similar to calling `.kill()` on the child process except
|
||||
the error passed to the callback will be an `AbortError`:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
@@ -712,6 +891,17 @@ grep.on('error', (err) => {
|
||||
controller.abort(); // Stops the child process
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from '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
|
||||
```
|
||||
|
||||
#### `options.detached`
|
||||
|
||||
<!-- YAML
|
||||
@@ -744,8 +934,21 @@ controlling terminal.
|
||||
Example of a long-running process, by detaching and also ignoring its parent
|
||||
`stdio` file descriptors, in order to ignore the parent's termination:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const process = require('node:process');
|
||||
|
||||
const subprocess = spawn(process.argv[0], ['child_program.js'], {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
});
|
||||
|
||||
subprocess.unref();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from 'node:child_process';
|
||||
import process from 'node:process';
|
||||
|
||||
const subprocess = spawn(process.argv[0], ['child_program.js'], {
|
||||
detached: true,
|
||||
@@ -757,11 +960,25 @@ subprocess.unref();
|
||||
|
||||
Alternatively one can redirect the child process' output into files:
|
||||
|
||||
```js
|
||||
const fs = require('node:fs');
|
||||
```cjs
|
||||
const { openSync } = require('node:fs');
|
||||
const { spawn } = require('node:child_process');
|
||||
const out = fs.openSync('./out.log', 'a');
|
||||
const err = fs.openSync('./out.log', 'a');
|
||||
const out = openSync('./out.log', 'a');
|
||||
const err = openSync('./out.log', 'a');
|
||||
|
||||
const subprocess = spawn('prg', [], {
|
||||
detached: true,
|
||||
stdio: [ 'ignore', out, err ],
|
||||
});
|
||||
|
||||
subprocess.unref();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { openSync } from 'node:fs';
|
||||
import { spawn } from 'node:child_process';
|
||||
const out = openSync('./out.log', 'a');
|
||||
const err = openSync('./out.log', 'a');
|
||||
|
||||
const subprocess = spawn('prg', [], {
|
||||
detached: true,
|
||||
@@ -852,8 +1069,24 @@ pipes between the parent and child. The value is one of the following:
|
||||
words, stdin, stdout, and stderr) a pipe is created. For fd 3 and up, the
|
||||
default is `'ignore'`.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const process = require('node: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'] });
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from 'node:child_process';
|
||||
import process from 'node:process';
|
||||
|
||||
// Child will use parent's stdios.
|
||||
spawn('prg', [], { stdio: 'inherit' });
|
||||
@@ -963,7 +1196,7 @@ If the process times out or has a non-zero exit code, this method will throw an
|
||||
function. Any input containing shell metacharacters may be used to trigger
|
||||
arbitrary command execution.**
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { execFileSync } = require('node:child_process');
|
||||
|
||||
try {
|
||||
@@ -991,6 +1224,34 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { execFileSync } from 'node:child_process';
|
||||
|
||||
try {
|
||||
const stdout = execFileSync('my-script.sh', ['my-arg'], {
|
||||
// Capture stdout and stderr from child process. Overrides the
|
||||
// default behavior of streaming child stderr to the parent stderr
|
||||
stdio: 'pipe',
|
||||
|
||||
// Use utf8 encoding for stdio pipes
|
||||
encoding: 'utf8',
|
||||
});
|
||||
|
||||
console.log(stdout);
|
||||
} catch (err) {
|
||||
if (err.code) {
|
||||
// Spawning child process failed
|
||||
console.error(err.code);
|
||||
} else {
|
||||
// Child was spawned but exited with non-zero exit code
|
||||
// Error contains any stdout and stderr from the child
|
||||
const { stdout, stderr } = err;
|
||||
|
||||
console.error({ stdout, stderr });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `child_process.execSync(command[, options])`
|
||||
|
||||
<!-- YAML
|
||||
@@ -1176,7 +1437,7 @@ streams of a child process have been closed. This is distinct from the
|
||||
streams. The `'close'` event will always emit after [`'exit'`][] was
|
||||
already emitted, or [`'error'`][] if the child failed to spawn.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const ls = spawn('ls', ['-lh', '/usr']);
|
||||
|
||||
@@ -1193,6 +1454,23 @@ ls.on('exit', (code) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from '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}`);
|
||||
});
|
||||
```
|
||||
|
||||
### Event: `'disconnect'`
|
||||
|
||||
<!-- YAML
|
||||
@@ -1373,7 +1651,7 @@ argument is given, the process will be sent the `'SIGTERM'` signal. See
|
||||
signal(7) for a list of available signals. This function returns `true` if
|
||||
kill(2) succeeds, and `false` otherwise.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const grep = spawn('grep', ['ssh']);
|
||||
|
||||
@@ -1386,6 +1664,19 @@ grep.on('close', (code, signal) => {
|
||||
grep.kill('SIGHUP');
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from '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');
|
||||
```
|
||||
|
||||
The [`ChildProcess`][] object may emit an [`'error'`][] event if the signal
|
||||
cannot be delivered. Sending a signal to a child process that has already exited
|
||||
is not an error but may have unforeseen consequences. Specifically, if the
|
||||
@@ -1406,8 +1697,7 @@ On Linux, child processes of child processes will not be terminated
|
||||
when attempting to kill their parent. This is likely to happen when running a
|
||||
new process in a shell or with the use of the `shell` option of `ChildProcess`:
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
|
||||
const subprocess = spawn(
|
||||
@@ -1427,6 +1717,26 @@ setTimeout(() => {
|
||||
}, 2000);
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from '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);
|
||||
```
|
||||
|
||||
### `subprocess[Symbol.dispose]()`
|
||||
|
||||
<!-- YAML
|
||||
@@ -1464,7 +1774,7 @@ Returns the process identifier (PID) of the child process. If the child process
|
||||
fails to spawn due to errors, then the value is `undefined` and `error` is
|
||||
emitted.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const grep = spawn('grep', ['ssh']);
|
||||
|
||||
@@ -1472,6 +1782,14 @@ console.log(`Spawned child pid: ${grep.pid}`);
|
||||
grep.stdin.end();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from 'node:child_process';
|
||||
const grep = spawn('grep', ['ssh']);
|
||||
|
||||
console.log(`Spawned child pid: ${grep.pid}`);
|
||||
grep.stdin.end();
|
||||
```
|
||||
|
||||
### `subprocess.ref()`
|
||||
|
||||
<!-- YAML
|
||||
@@ -1482,8 +1800,22 @@ Calling `subprocess.ref()` after making a call to `subprocess.unref()` will
|
||||
restore the removed reference count for the child process, forcing the parent
|
||||
to wait for the child to exit before exiting itself.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const process = require('node:process');
|
||||
|
||||
const subprocess = spawn(process.argv[0], ['child_program.js'], {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
});
|
||||
|
||||
subprocess.unref();
|
||||
subprocess.ref();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from 'node:child_process';
|
||||
import process from 'node:process';
|
||||
|
||||
const subprocess = spawn(process.argv[0], ['child_program.js'], {
|
||||
detached: true,
|
||||
@@ -1533,23 +1865,35 @@ message might not be the same as what is originally sent.
|
||||
|
||||
For example, in the parent script:
|
||||
|
||||
```js
|
||||
const cp = require('node:child_process');
|
||||
const n = cp.fork(`${__dirname}/sub.js`);
|
||||
```cjs
|
||||
const { fork } = require('node:child_process');
|
||||
const forkedProcess = fork(`${__dirname}/sub.js`);
|
||||
|
||||
n.on('message', (m) => {
|
||||
console.log('PARENT got message:', m);
|
||||
forkedProcess.on('message', (message) => {
|
||||
console.log('PARENT got message:', message);
|
||||
});
|
||||
|
||||
// Causes the child to print: CHILD got message: { hello: 'world' }
|
||||
n.send({ hello: 'world' });
|
||||
forkedProcess.send({ hello: 'world' });
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { fork } from 'node:child_process';
|
||||
const forkedProcess = fork(`${import.meta.dirname}/sub.js`);
|
||||
|
||||
forkedProcess.on('message', (message) => {
|
||||
console.log('PARENT got message:', message);
|
||||
});
|
||||
|
||||
// Causes the child to print: CHILD got message: { hello: 'world' }
|
||||
forkedProcess.send({ hello: 'world' });
|
||||
```
|
||||
|
||||
And then the child script, `'sub.js'` might look like this:
|
||||
|
||||
```js
|
||||
process.on('message', (m) => {
|
||||
console.log('CHILD got message:', m);
|
||||
process.on('message', (message) => {
|
||||
console.log('CHILD got message:', message);
|
||||
});
|
||||
|
||||
// Causes the parent to print: PARENT got message: { foo: 'bar', baz: null }
|
||||
@@ -1592,11 +1936,30 @@ used to implement flow control.
|
||||
The `sendHandle` argument can be used, for instance, to pass the handle of
|
||||
a TCP server object to the child process as illustrated in the example below:
|
||||
|
||||
```js
|
||||
const subprocess = require('node:child_process').fork('subprocess.js');
|
||||
```cjs
|
||||
const { fork } = require('node:child_process');
|
||||
const { createServer } = require('node:net');
|
||||
|
||||
const subprocess = fork('subprocess.js');
|
||||
|
||||
// Open up the server object and send the handle.
|
||||
const server = require('node:net').createServer();
|
||||
const server = createServer();
|
||||
server.on('connection', (socket) => {
|
||||
socket.end('handled by parent');
|
||||
});
|
||||
server.listen(1337, () => {
|
||||
subprocess.send('server', server);
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { fork } from 'node:child_process';
|
||||
import { createServer } from 'node:net';
|
||||
|
||||
const subprocess = fork('subprocess.js');
|
||||
|
||||
// Open up the server object and send the handle.
|
||||
const server = createServer();
|
||||
server.on('connection', (socket) => {
|
||||
socket.end('handled by parent');
|
||||
});
|
||||
@@ -1632,14 +1995,39 @@ Similarly, the `sendHandler` argument can be used to pass the handle of a
|
||||
socket to the child process. The example below spawns two children that each
|
||||
handle connections with "normal" or "special" priority:
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { fork } = require('node:child_process');
|
||||
const { createServer } = require('node:net');
|
||||
|
||||
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 });
|
||||
const server = 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);
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { fork } from 'node:child_process';
|
||||
import { createServer } from 'node:net';
|
||||
|
||||
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 = createServer({ pauseOnConnect: true });
|
||||
server.on('connection', (socket) => {
|
||||
|
||||
// If this is special priority...
|
||||
@@ -1763,7 +2151,7 @@ In the following example, only the child's fd `1` (stdout) is configured as a
|
||||
pipe, so only the parent's `subprocess.stdio[1]` is a stream, all other values
|
||||
in the array are `null`.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const assert = require('node:assert');
|
||||
const fs = require('node:fs');
|
||||
const child_process = require('node:child_process');
|
||||
@@ -1786,6 +2174,29 @@ assert.strictEqual(subprocess.stdio[2], null);
|
||||
assert.strictEqual(subprocess.stdio[2], subprocess.stderr);
|
||||
```
|
||||
|
||||
```mjs
|
||||
import assert from 'node:assert';
|
||||
import fs from 'node:fs';
|
||||
import child_process from '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);
|
||||
```
|
||||
|
||||
The `subprocess.stdio` property can be `undefined` if the child process could
|
||||
not be successfully spawned.
|
||||
|
||||
@@ -1805,7 +2216,7 @@ then this will be `null`.
|
||||
`subprocess.stdout` is an alias for `subprocess.stdio[1]`. Both properties will
|
||||
refer to the same value.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
|
||||
const subprocess = spawn('ls');
|
||||
@@ -1815,6 +2226,16 @@ subprocess.stdout.on('data', (data) => {
|
||||
});
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from 'node:child_process';
|
||||
|
||||
const subprocess = spawn('ls');
|
||||
|
||||
subprocess.stdout.on('data', (data) => {
|
||||
console.log(`Received chunk ${data}`);
|
||||
});
|
||||
```
|
||||
|
||||
The `subprocess.stdout` property can be `null` or `undefined`
|
||||
if the child process could not be successfully spawned.
|
||||
|
||||
@@ -1831,8 +2252,21 @@ include the child in its reference count, allowing the parent to exit
|
||||
independently of the child, unless there is an established IPC channel between
|
||||
the child and the parent.
|
||||
|
||||
```js
|
||||
```cjs
|
||||
const { spawn } = require('node:child_process');
|
||||
const process = require('node:process');
|
||||
|
||||
const subprocess = spawn(process.argv[0], ['child_program.js'], {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
});
|
||||
|
||||
subprocess.unref();
|
||||
```
|
||||
|
||||
```mjs
|
||||
import { spawn } from 'node:child_process';
|
||||
import process from 'node:process';
|
||||
|
||||
const subprocess = spawn(process.argv[0], ['child_program.js'], {
|
||||
detached: true,
|
||||
|
||||
Reference in new issue
Block a user