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


生成一个 shell,然后在该 shell 中执行 command,并缓存任何生成的输出。传递给 exec 函数的 command 字符串会由 shell 直接处理,特殊字符(根据 shell 不同而不同)需要相应处理:

【Spawns a shell then executes the command within that shell, buffering any generated output. The command string passed to the exec function is processed directly by the shell and special characters (vary based on shell) need to be dealt with accordingly:】

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.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.

不要将未经清理的用户输入传递给此函数。任何包含 shell 元字符的输入都可能被用来触发任意命令执行。

如果提供了 callback 函数,它将使用参数 (error, stdout, stderr) 被调用。成功时,error 将为 null。发生错误时,error 将是 Error 的一个实例。error.code 属性将是进程的退出码。按照惯例,任何非 0 的退出码都表示错误。error.signal 将是终止进程的信号。

【If a callback function is provided, it is called with the arguments (error, stdout, stderr). On success, error will be null. On error, error will be an instance of Error. The error.code property will be the exit code of the process. By convention, any exit code other than 0 indicates an error. error.signal will be the signal that terminated the process.】

stdoutstderr 参数传递给回调时,将包含子进程的 stdout 和 stderr 输出。默认情况下,Node.js 会将输出解码为 UTF-8,并将字符串传递给回调。可以使用 encoding 选项来指定用于解码 stdout 和 stderr 输出的字符编码。如果 encoding'buffer' 或未识别的字符编码,则会将 Buffer 对象传递给回调。

【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 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.】

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

如果 timeout 大于 0,当子进程运行时间超过 timeout 毫秒时,父进程将发送由 killSignal 属性指定的信号(默认是 'SIGTERM')。

【If timeout is greater than 0, the parent process will send the signal identified by the killSignal property (the default is 'SIGTERM') if the child process runs longer than timeout milliseconds.】

exec(3) POSIX 系统调用不同,child_process.exec() 不会替换现有进程,而是使用 shell 来执行命令。

【Unlike the exec(3) POSIX system call, child_process.exec() does not replace the existing process and uses a shell to execute the command.】

如果以其 util.promisify()ed 版本调用此方法,它将返回一个带有 stdoutstderr 属性的 ObjectPromise。返回的 ChildProcess 实例作为 child 属性附加到该 Promise 上。如果发生错误(包括导致退出代码非 0 的任何错误),将返回一个被拒绝的 Promise,并带有回调中提供的相同 error 对象,但会额外包含两个属性 stdoutstderr

【If this method is invoked as its util.promisify()ed version, it returns a Promise for an Object with stdout and stderr properties. The returned ChildProcess instance is attached to the Promise as a child property. In 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.】

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();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();

如果启用了 signal 选项,那么对相应的 AbortController 调用 .abort() 类似于对子进程调用 .kill(),只是传递给回调的错误将是 AbortError

【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:】

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();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();