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.stdio
detached
<boolean> 準備子進程獨立於其父進程運行。具體行為取決於平台,請參閱options.detached
uid
<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
對象上的屬性公開給父級,為subprocess.stdio[fd]
subprocess.stdin
subprocess.stdout
subprocess.stderr
/dev/fd/2
或/dev/stdout
。 -
'overlapped'
:與'pipe'
相同,隻是在句柄上設置了FILE_FLAG_OVERLAPPED
標誌。這對於子進程的 stdio 句柄上的重疊 I/O 是必要的。有關詳細信息,請參閱docs。這與非 Windows 係統上的'pipe'
完全相同。 -
'ipc'
:創建一個 IPC 通道,用於在父子之間傳遞消息/文件說明符。ChildProcess
subprocess.send()
process.send()
process.disconnect()
'disconnect'
'message'
不支持以
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])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。