From 0debdac9da67d744f4706a1c8ccb537b44ce3647 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Thu, 5 Sep 2024 04:47:48 -0400 Subject: [PATCH] doc, child_process: add esm snippets PR-URL: https://github.com/nodejs/node/pull/53616 Reviewed-By: Chemi Atlow --- doc/api/child_process.md | 548 +++++++++++++++++++++++++++++++++++---- 1 file changed, 491 insertions(+), 57 deletions(-) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index b08ba65917aadc..045f34352a92ee 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -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']); - -bat.stdout.on('data', (data) => { - console.log(data.toString()); -}); +```cjs +// OR... +const { exec, spawn } = require('node:child_process'); -bat.stderr.on('data', (data) => { - console.error(data.toString()); +exec('my.bat', (err, stdout, stderr) => { + if (err) { + console.error(err); + return; + } + console.log(stdout); }); -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])`