child_process.spawn(command[, args][, options])
| 版本 | 變化 |
|---|---|
| v16.4.0、v14.18.0 |
|
| v15.13.0、v14.18.0 | 添加了超時。 |
| v15.11.0、v14.18.0 | 添加了AbortSignal 的 killSignal。 |
| v15.5.0、v14.17.0 | 添加了AbortSignal 支持。 |
| v13.2.0、v12.16.0 | 現在支持 |
| v8.8.0 | 現在支持 |
| v6.4.0 | 現在支持 |
| v5.7.0 | 現在支持 |
| v0.1.90 | 添加於:v0.1.90 |
參數
command<string> 要運行的命令。args<string[]> 字符串參數列表。options<Object>cwd<string> | <URL> 子進程的當前工作目錄。env<Object> 環境鍵值對。 默認:process.env。argv0<string> 顯式設置發送給子進程的argv[0]的值。如果未指定,這將設置為command。stdio<Array> | <string> 孩子的 stdio 配置(參見)。options.stdiodetached<boolean> 準備子進程獨立於其父進程運行。具體行為取決於平台,請參閱)。options.detacheduid<number> 設置進程的用戶身份(參見)。setuid(2)gid<number> 設置進程的組標識(參見)。setgid(2)serialization<string> 指定用於在進程之間發送消息的序列化類型。可能的值為'json'和'advanced'。有關詳細信息,請參閱Advanced serialization。 默認:'json'。shell<boolean> | <string> 如果true,在 shell 內運行command。在 Unix 上使用'/bin/sh',在 Windows 上使用process.env.ComSpec。可以將不同的 shell 指定為字符串。請參閱 Shell requirements 和 Default Windows shell 。 默認:false(無 shell )。windowsVerbatimArguments<boolean> 在 Windows 上不對參數進行引用或轉義。在 Unix 上被忽略。當指定shell並且是 CMD 時,它會自動設置為true。 默認:false。windowsHide<boolean> 隱藏通常在 Windows 係統上創建的子進程控製台窗口。 默認:false。signal<AbortSignal> 允許使用 AbortSignal 中止子進程。timeout<number> 允許進程運行的最長時間(以毫秒為單位)。 默認:undefined。killSignal<string> | <integer> 生成的進程將被超時或中止信號殺死時使用的信號值。 默認:'SIGTERM'。
- 返回: <ChildProcess>
child_process.spawn() 方法使用給定的 command 生成一個新進程,在 args 中帶有 命令行 參數。如果省略,args 默認為空數組。
如果啟用了 shell 選項,請不要將未經處理的用戶輸入傳遞給此函數。任何包含 shell 元字符的輸入都可用於觸發任意命令執行。
第三個參數可用於指定其他選項,具有以下默認值:
const defaults = {
cwd: undefined,
env: process.env
};
使用cwd 指定生成進程的工作目錄。如果沒有給出,默認是繼承當前工作目錄。如果給定,但路徑不存在,子進程會發出 ENOENT 錯誤並立即退出。 ENOENT 也會在命令不存在時發出。
使用 env 指定對新進程可見的環境變量,默認為 。process.env
env 中的 undefined 值將被忽略。
運行 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}`);
});
示例:一種非常精細的運行方式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}`);
}
});
檢查失敗的示例 spawn :
const { spawn } = require('node:child_process');
const subprocess = spawn('bad_command');
subprocess.on('error', (err) => {
console.error('Failed to start subprocess.');
});
某些平台(macOS、Linux)將使用 argv[0] 的值作為進程標題,而其他平台(Windows、SunOS)將使用 command 。
Node.js 當前在啟動時用process.execPath 覆蓋argv[0],因此Node.js 子進程中的process.argv[0] 將不匹配從父進程傳遞給spawn 的argv0 參數,使用process.argv0 檢索它而是屬性。
如果啟用了 signal 選項,則在相應的 AbortController 上調用 .abort() 與在子進程上調用 .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
options.detached#
在 Windows 上,將 options.detached 設置為 true 可以讓子進程在父進程退出後繼續運行。孩子將擁有自己的控製台窗口。一旦為子進程啟用,它就不能被禁用。
在非 Windows 平台上,如果 options.detached 設置為 true ,則子進程將成為新進程組和會話的領導者。子進程可以在父進程退出後繼續運行,無論它們是否分離。有關詳細信息,請參閱 。setsid(2)
默認情況下,父級將等待分離的子級退出。要防止父級等待給定的subprocess 退出,請使用subprocess.unref() 方法。這樣做會導致父級的事件循環不將子級包含在其引用計數中,從而允許父級獨立於子級退出,除非子級和父級之間已建立 IPC 通道。
當使用detached 選項啟動long-running 進程時,進程將不會在父進程退出後繼續在後台運行,除非它提供了未連接到父進程的stdio 配置。如果繼承父級的stdio,則子級將保持連接到控製終端。
long-running 進程的示例,通過分離並忽略其父 stdio 文件說明符,以忽略父進程的終止:
const { spawn } = require('node:child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore'
});
subprocess.unref();
或者,可以將子進程的輸出重定向到文件中:
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();
options.stdio#
| 版本 | 變化 |
|---|---|
| v15.6.0、v14.18.0 | 添加了 |
| v3.3.1 | 值 |
| v0.7.10 | 添加於:v0.7.10 |
options.stdio 選項用於配置在父進程和子進程之間建立的管道。默認情況下,孩子的 stdin、stdout 和 stderr 被重定向到 對象上相應的 ChildProcess 、 subprocess.stdin 和 subprocess.stdout 流。這相當於將 subprocess.stderr 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。 fds 0、1 和 2 分別對應於 stdin、stdout 和 stderr。可以指定額外的 fd 來在父子節點之間創建額外的管道。該值為以下之一:
-
'pipe':在子進程和父進程之間創建一個管道。管道的父端作為child_process對象上的屬性公開給父級,為。為 fds 0、1 和 2 創建的管道也可分別用作subprocess.stdio[fd]、subprocess.stdin和subprocess.stdout。目前,這些不是實際的 Unix 管道,因此子進程不能通過它們的說明符文件使用它們,例如subprocess.stderr/dev/fd/2或/dev/stdout。 -
'overlapped':與'pipe'相同,隻是在句柄上設置了FILE_FLAG_OVERLAPPED標誌。這對於子進程的 stdio 句柄上的重疊 I/O 是必要的。有關詳細信息,請參閱docs。這與非 Windows 係統上的'pipe'完全相同。 -
'ipc':創建一個 IPC 通道,用於在父子之間傳遞消息/文件說明符。最多可以有一個 IPC stdio 文件說明符。設置此選項將啟用ChildProcess方法。如果子進程是 Node.js 進程,則 IPC 通道的存在將啟用subprocess.send()和process.send()方法,以及子進程內的process.disconnect()和'disconnect'事件。'message'不支持以
以外的任何方式訪問 IPC 通道 fd 或將 IPC 通道與不是 Node.js 實例的子進程一起使用。process.send() -
'ignore':指示 Node.js 忽略子級中的 fd。雖然 Node.js 將始終為其生成的進程打開 fds 0、1 和 2,但將 fd 設置為'ignore'將導致 Node.js 打開/dev/null並將其附加到子 fd 上。 -
'inherit':通過相應的 stdio 流傳入/傳出父進程。在前三個位置,這分別相當於process.stdin、process.stdout和process.stderr。在任何其他位置,相當於'ignore'。 -
<Stream> 對象:與子進程共享引用 tty、文件、套接字或管道的可讀或可寫流。流的底層文件說明符在子進程中複製到與
stdio數組中的索引對應的 fd。流必須有一個底層說明符(文件流在'open'事件發生之前沒有)。 -
正整數:整數值被解釋為當前在父進程中打開的文件說明符。它與子進程共享,類似於如何共享 <Stream> 對象。 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'] });
值得注意的是,當父子進程之間建立了 IPC 通道,並且子進程是 Node.js 進程時,子進程會以未引用的 IPC 通道啟動(使用 unref() ),直到子進程注冊事件處理程序對於 事件或 'disconnect' 事件。這允許子進程正常退出,而進程不會被打開的 IPC 通道保持打開狀態。'message'
在Unix-like 操作係統上, 方法在將事件循環與子進程分離之前同步執行內存操作。具有大量內存占用的應用程序可能會發現頻繁的 child_process.spawn() 調用是一個瓶頸。有關詳細信息,請參閱V8 issue 7381。child_process.spawn()
另請參閱: 和 child_process.exec() 。child_process.fork()
相關用法
- Node.js child_process.fork(modulePath[, args][, options])用法及代碼示例
- Node.js child_process.exec(command[, options][, callback])用法及代碼示例
- Node.js child_process.execFile(file[, args][, options][, callback])用法及代碼示例
- Node.js certificate.verifySpkac(spkac[, encoding])用法及代碼示例
- Node.js console.timeEnd()用法及代碼示例
- Node.js crypto.randomFill()用法及代碼示例
- Node.js crypto.createHmac()用法及代碼示例
- Node.js crypto.randomFillSync(buffer[, offset][, size])用法及代碼示例
- Node.js console.countReset()用法及代碼示例
- Node.js cluster.worker用法及代碼示例
- Node.js crypto.constants用法及代碼示例
- Node.js crypto.randomInt([min, ]max[, callback])用法及代碼示例
- Node.js crypto.publicEncrypt()用法及代碼示例
- Node.js console.trace()用法及代碼示例
- Node.js console.timeLog()用法及代碼示例
- Node.js console.timeStamp()用法及代碼示例
- Node.js crypto.publicDecrypt()用法及代碼示例
- Node.js console.dir()用法及代碼示例
- Node.js crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)用法及代碼示例
- Node.js console.log()用法及代碼示例
- Node.js crypto.createHash()用法及代碼示例
- Node.js crypto.hkdfSync()用法及代碼示例
- Node.js crypto.randomFillSync()用法及代碼示例
- Node.js crypto.checkPrime()用法及代碼示例
- Node.js clienthttp2session.request()用法及代碼示例
注:本文由純淨天空篩選整理自nodejs.org大神的英文原創作品 child_process.spawn(command[, args][, options])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。
