Thực Thi
Thực thi quá trình cho con người.
Tại Sao
Gói này cải thiện child_process với:
- Promise interface.
- Scripts interface, như
zx
. - Tích hợp Windows support, bao gồm các tệp nhị phân shebang.
- Thực hiện locally installed binaries mà không cần
npx
. - Tự động kết thúc các tiến trình con Cleans up khi tiến trình cha kết thúc.
- Graceful termination.
- Lấy interleaved output từ
stdout
vàstderr
giống như thông tin được in trên cửa sổ terminal. - Strips the final newline từ kết quả đầu ra để bạn không cần phải dùng
stdout.trim()
. - Các phương thức tiện lợi để kết nối đường ống của quá trình input và output.
- Có thể chỉ định tệp và đối số as a single string mà không cần sử dụng một shell.
- Verbose mode cho mục đích gỡ lỗi.
- Các lỗi mô tả chi tiết hơn.
- Bộ đệm tối đa lớn hơn: 100 MB thay vì 1 MB.
Cài Đặt
npm install execa
Sử Dụng
Giao diện Promise
import {execa} from 'execa';
const {stdout} = await execa('echo', ['unicorns']);
console.log(stdout);
//=> ‘unicorns’
Giao diện Tập Lệnh
Để biết thêm thông tin về tập lệnh Execa, vui lòng xem this page.
Cơ Bản
import {$} from 'execa';
const branch = await $`git branch --show-current`;
await $`dep deploy --branch=${branch}`;
Nhiều đối số
import {$} from 'execa';
const args = ['unicorns', '&', 'rainbows!'];
const {stdout} = await $`echo ${args}`;
console.log(stdout);
//=> ‘unicorns & rainbows!’
Với tùy chọn
import {$} from 'execa';
await $({stdio: 'inherit'})`echo unicorns`;
//=> ‘unicorns’
Tùy chọn chung
import {$} from 'execa';
const $$ = $({stdio: 'inherit'});
await $$`echo unicorns`;
//=> 'unicorns'
await $$`echo rainbows`;
//=> ‘rainbows’
Chế độ chi tiết
> node file.js
unicorns
rainbows
> NODE_DEBUG=execa node file.js
[16:50:03.305] echo unicorns
unicorns
[16:50:03.308] echo rainbows
rainbows
Đầu Vào/Đầu Ra
Chuyển hướng đầu ra sang tệp
import {execa} from 'execa';
// Similar to `echo unicorns > stdout.txt` in Bash
await execa('echo', ['unicorns']).pipeStdout('stdout.txt');
// Similar to `echo unicorns 2> stdout.txt` in Bash
await execa('echo', ['unicorns']).pipeStderr('stderr.txt');
// Similar to `echo unicorns &> stdout.txt` in Bash
await execa('echo', ['unicorns'], {all: true}).pipeAll('all.txt');
Chuyển hướng đầu vào từ tệp
import {execa} from 'execa';
// Similar to `cat < stdin.txt` in Bash
const {stdout} = await execa('cat', {inputFile: 'stdin.txt'});
console.log(stdout);
//=> ‘unicorns’
Lưu và kết nối đầu ra từ quá trình con
import {execa} from 'execa';
const {stdout} = await execa('echo', ['unicorns']).pipeStdout(process.stdout);
// Prints `unicorns`
console.log(stdout);
// Also returns ‘unicorns’
Kết nối nhiều quá trình
import {execa} from 'execa';
// Similar to `echo unicorns | cat` in Bash
const {stdout} = await execa('echo', ['unicorns']).pipeStdout(execa('cat'));
console.log(stdout);
//=> ‘unicorns’
Xử Lý Lỗi
import {execa} from 'execa';
// Catching an error
try {
await execa('unknown', ['command']);
} catch (error) {
console.log(error);
/*
{
message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
errno: -2,
code: 'ENOENT',
syscall: 'spawn unknown',
path: 'unknown',
spawnargs: ['command'],
originalMessage: 'spawn unknown ENOENT',
shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
command: 'unknown command',
escapedCommand: 'unknown command',
stdout: '',
stderr: '',
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
*/
}
Kết thúc êm ái
Sử dụng SIGTERM, và sau 2 giây, kết thúc bằng SIGKILL.
const subprocess = execa('node');
setTimeout(() => {
subprocess.kill('SIGTERM', {
forceKillAfterTimeout: 2000
});
}, 1000);
API
Phương Thức
execa(file, arguments?, options?)
Thực thi một lệnh bằng cách sử dụng file ...arguments
. arguments
được chỉ định dưới dạng một mảng chuỗi. Trả về một childProcess.
Đối số có thể là automatically escaped. Chúng có thể chứa bất kỳ ký tự nào, bao gồm khoảng trắng.
Đây là phương pháp ưa thích khi thực thi các lệnh đơn.
execaNode(scriptPath, arguments?, options?)
Thực thi một tệp Node.js bằng cách sử dụng node scriptPath ...arguments
. arguments
được chỉ định dưới dạng một mảng chuỗi. Trả về một childProcess.
Đối số có thể là automatically escaped. Chúng có thể chứa bất kỳ ký tự nào, bao gồm khoảng trắng.
Đây là phương pháp ưa thích khi thực thi các tệp Node.js.
Tương tự child_process#fork():
- Sử dụng phiên bản Node hiện tại và tùy chọn mặc định. Điều này có thể bị ghi đè bằng cách sử dụng các tùy chọn nodePath và nodeOptions.
- Không thể sử dụng tùy chọn shell
- Một kênh bổ sung ipc được truyền vào stdio
$command
Thực thi một lệnh. Chuỗi command
bao gồm cả file
và các arguments
của nó. Trả về một childProcess.
Đối số có thể là automatically escaped. Chúng có thể chứa bất kỳ ký tự nào, nhưng khoảng trắng phải sử dụng ${}
như $
echo ${‘có khoảng trắng’}“.
Đây là phương pháp ưa thích khi thực thi nhiều lệnh trong tệp tập lệnh.
Chuỗi command
có thể chèn bất kỳ ${value}
nào với các loại sau: chuỗi, số, childProcess hoặc một mảng của những loại này. Ví dụ: $
echo one ${‘two’} ${3} ${[‘four’, ‘five’]}`. Đối với
${childProcess}`, đầu ra của quá trình được sử dụng.
Để biết thêm thông tin, vui lòng xem this section và this page.
$(options)
Trả về một phiên bản mới của $ nhưng với các options
mặc định khác. Các lần gọi liên tiếp được gộp lại với các lần gọi trước đó.
Điều này có thể được sử dụng để:
- Đặt các tùy chọn cho một lệnh cụ thể:
$(options)
lệnh“ - Chia sẻ các tùy chọn cho nhiều lệnh:
const $$ = $(options); $$
lệnh; $$
lệnhKhác;
execaCommand(command, options?)
Thực thi một lệnh. Chuỗi command
bao gồm cả file
và các arguments
của nó. Trả về một childProcess.
Đối số có thể là automatically escaped. Chúng có thể chứa bất kỳ ký tự nào, nhưng khoảng trắng phải được thoát với dấu gạch chéo như execaCommand('echo has\\ space')
.
Đây là phương pháp ưa thích khi thực thi một chuỗi command
do người dùng cung cấp, ví dụ trong một môi trường REPL.
execaSync(file, arguments?, options?)
Giống với execa() nhưng đồng bộ.
Trả về hoặc ném một childProcessResult.
$.synccommand
Giống với $command
nhưng đồng bộ.
Trả về hoặc ném một childProcessResult.
execaCommandSync(command, options?)
Giống với execaCommand() nhưng đồng bộ.
Trả về hoặc ném một childProcessResult.
Cú pháp Shell
Đối với tất cả methods above, không có trình thông dịch shell (Bash, cmd.exe, v.v.) được sử dụng trừ khi shell option được thiết lập. Điều này có nghĩa là các ký tự và biểu thức cụ thể của shell ($biến
, &&
, ||
, ;
, |
, v.v.) không có ý nghĩa đặc biệt và không cần phải thoát ra.
childProcess
Giá trị trả về của tất cả asynchronous methods đều là:
- Một
Promise
giải quyết hoặc từ chối với một childProcessResult. - Một child_process instance với các phương thức và thuộc tính bổ sung sau đây.
kill(signal?, options?)
Giống với child_process#kill() gốc ngoại trừ: nếu signal
là SIGTERM
(giá trị mặc định) và quá trình con không kết thúc sau 5 giây, thì gửi SIGKILL
để kết thúc nó.
Lưu ý rằng việc kết thúc êm ái này không hoạt động trên Windows, vì Windows doesn’t support signals (SIGKILL
và SIGTERM
có hiệu lực tương tự việc kết thúc bằng cách bắt buộc kết thúc quá trình ngay lập tức.) Nếu bạn muốn đạt được kết thúc êm ái trên Windows, bạn phải sử dụng các phương tiện khác, chẳng hạn như taskkill.
options.forceKillAfterTimeout
Loại: number | false
Giá trị mặc định: 5000
Milliseconds để chờ quá trình con kết thúc trước khi gửi SIGKILL
.
Có thể vô hiệu hóa bằng cách sử dụng false
.
all
Loại: ReadableStream | undefined
Luồng kết hợp/lẫn lộn stdout và stderr.
Điều này là undefined
nếu một trong những điều sau xảy ra:
- all option là
false
(giá trị mặc định) - cả hai tùy chọn stdout và stderr được thiết lập thành ‘inherit’, ‘ipc’, Stream or integer
pipeStdout(target)
Pipe đầu ra stdout
của quá trình con đến target
, có thể là:
- Một execa() return value khác
- Một writable stream
- Một file path string
Nếu target
là một execa() return value khác, thì nó sẽ được trả về. Ngược lại, giá trị trả về gốc của execa()
sẽ được trả về. Điều này cho phép chuỗi pipeStdout()
sau đó await
final result.
stdout option phải được giữ nguyên là pipe
, giá trị mặc định của nó.
pipeStderr(target)
Tương tự như pipeStdout() nhưng đang đẩy đầu ra stderr
của quá trình con thay vì stdout
.
stderr option phải được giữ nguyên là pipe
, giá trị mặc định của nó.
pipeAll(target)
Kết hợp cả hai pipeStdout() và pipeStderr().
Hoặc stdout option hoặc stderr option phải được giữ nguyên là pipe
, giá trị mặc định của họ. Ngoài ra, all option phải được thiết lập thành true
.
childProcessResult
Loại: object
Kết quả của việc thực thi quá trình con. Trên thành công, đây là một đối tượng thuần túy. Trong trường hợp thất bại, đây cũng là một thể hiện của Error
.
Quá trình con fails khi:
- exit code không phải là
0
- nó đã được killed với một signal
- timing out
- being canceled
- không đủ bộ nhớ hoặc đã có quá nhiều quá trình con
command
Loại: string
Tệp và các đối số đã chạy, cho mục đích ghi nhật ký.
Đây không được thoát và không nên được thực thi trực tiếp như một quá trình, bao gồm việc sử dụng execa() hoặc execaCommand().
escapedCommand
Loại: string
Giống với command nhưng đã được thoát.
Điều này được dự định để được sao chép và dán vào một shell, cho mục đích gỡ lỗi. Vì việc thoát khá cơ bản, điều này không nên được thực thi trực tiếp như một quá trình, bao gồm việc sử dụng execa() hoặc execaCommand().
exitCode
Loại: number
Mã thoát số của quá trình đã chạy.
stdout
Loại: string | Buffer
Đầu ra của quá trình trên stdout.
stderr
Loại: string | Buffer
Đầu ra của quá trình trên stderr.
all
Loại: string | Buffer | undefined
Đầu ra của quá trình với stdout
và stderr
được lẫn vào nhau.
Điều này là undefined
nếu:
- all option là
false
(giá trị mặc định) - Đã sử dụng
execaSync()
failed
Loại: boolean
Quá trình có thất bại trong quá trình chạy hay không.
timedOut
Loại: boolean
Quá trình có quá thời gian chạy hay không.
isCanceled
Loại: boolean
Quá trình đã bị hủy bỏ hay không.
Bạn có thể hủy quá trình đã bắt đầu bằng cách sử dụng tùy chọn signal.
killed
Loại: boolean
Quá trình đã bị kết thúc bằng tín hiệu hay không.
signal
Loại: string | undefined
Tên của tín hiệu được sử dụng để kết thúc quá trình. Ví dụ: SIGFPE
.
Nếu một tín hiệu kết thúc quá trình, thuộc tính này sẽ được định nghĩa và được bao gồm trong thông báo lỗi. Nếu không, nó sẽ là undefined
.
signalDescription
Loại: string | undefined
Mô tả thân thiện với con người về tín hiệu được sử dụng để kết thúc quá trình. Ví dụ: Lỗi tính toán dấu phẩy động
.
Nếu một tín hiệu kết thúc quá trình, thuộc tính này sẽ được định nghĩa và được bao gồm trong thông báo lỗi. Nếu không, nó sẽ là undefined
. Nó cũng là undefined
khi tín hiệu rất hiếm gặp, điều này hiếm khi xảy ra.
cwd
Loại: string
Thư mục hiện tại (cwd
) của lệnh nếu nó được cung cấp trong command options. Nếu không, nó sẽ là process.cwd()
.
message
Loại: string
Thông báo lỗi khi quá trình con thất bại trong quá trình chạy. Ngoài ra, nó còn chứa một số thông tin liên quan đến lý do tại sao quá trình con gặp lỗi.
Quá trình con stderr sau đó stdout được thêm vào cuối, cách nhau bằng dòng mới và không được lẫn vào nhau.
shortMessage
Loại: string
Đây giống với message property ngoại trừ rằng nó không bao gồm stdout/stderr của quá trình con.
originalMessage
Loại: string | undefined
Thông báo lỗi ban đầu. Điều này giống với thuộc tính message
, ngoại trừ rằng nó không bao gồm stdout/stderr của quá trình con cũng như một số thông tin bổ sung được thêm vào bởi Execa.
Điều này là undefined
trừ khi quá trình con kết thúc do một sự kiện error
hoặc thời gian chạy hết giờ.
options
Loại: object
cleanup
Loại: boolean
Giá trị mặc định: true
Kết thúc quá trình đã bắt đầu khi quá trình cha kết thúc trừ khi một trong những trường hợp sau xảy ra: – quá trình đã được detached – quá trình cha bị kết thúc đột ngột, ví dụ, bằng SIGKILL
thay vì SIGTERM
hoặc kết thúc bình thường
preferLocal
Loại: boolean
Giá trị mặc định: true
với $, false
trong trường hợp khác
Ưu tiên việc sử dụng các tệp nhị phân được cài đặt cục bộ khi tìm kiếm một tệp nhị phân để thực thi.
Nếu bạn $ npm install foo
, sau đó bạn có thể execa('foo')
.
localDir
Loại: string | URL
Giá trị mặc định: process.cwd()
Đường dẫn ưu tiên để tìm các tệp nhị phân được cài đặt cục bộ (sử dụng cùng với preferLocal
).
execPath
Loại: string
Giá trị mặc định: process.execPath
(Chương trình thực thi Node.js hiện tại)
Đường dẫn đến tệp thực thi Node.js được sử dụng trong các tiến trình con.
Điều này có thể là một đường dẫn tuyệt đối hoặc một đường dẫn tương đối đối với cwd option.
Yêu cầu preferLocal phải là true
.
Ví dụ, điều này có thể được sử dụng cùng với get-node để chạy một phiên bản Node.js cụ thể trong một tiến trình con.
buffer
Loại: boolean
Giá trị mặc định: true
Lưu trữ đầu ra từ quá trình bắt đầu. Khi đặt thành false
, bạn phải đọc đầu ra từ stdout và stderr (hoặc all nếu tùy chọn all là true
). Nếu không, hứa hẹn trả về sẽ không được giải quyết/từ chối.
Nếu quá trình đã bắt đầu thất bại, error.stdout, error.stderr, và error.all sẽ chứa dữ liệu đã lưu trữ.
input
Loại: string | Buffer | stream.Readable
Ghi một số dữ liệu đầu vào vào stdin
của tệp nhị phân của bạn.
Không được phép sử dụng luồng khi sử dụng các phương pháp đồng bộ.
Nếu dữ liệu đầu vào là một tệp, hãy sử dụng inputFile option thay vào đó.
inputFile
Loại: string
Sử dụng một tệp làm dữ liệu đầu vào cho stdin
của tệp nhị phân của bạn.
Nếu dữ liệu đầu vào không phải là một tệp, hãy sử dụng input option thay vào đó.
stdin
Loại: string | number | Stream | undefined
Giá trị mặc định: inherit
với $, pipe
trong trường hợp khác
Cùng các tùy chọn như stdio.
stdout
Loại: string | number | Stream | undefined
Giá trị mặc định: pipe
Cùng các tùy chọn như stdio.
stderr
Loại: string | number | Stream | undefined
Giá trị mặc định: pipe
Cùng các tùy chọn như stdio.
all
Loại: boolean
Giá trị mặc định: false
Thêm một thuộc tính .all
vào promise và resolved value. Thuộc tính này chứa đầu ra của quá trình với stdout
và stderr
được xen kẽ.
reject
Loại: boolean
Giá trị mặc định: true
Đặt giá trị này thành false
sẽ giải quyết hứa hẹn với lỗi thay vì từ chối nó.
stripFinalNewline
Loại: boolean
Giá trị mặc định: true
Loại bỏ newline character cuối cùng từ đầu ra.
extendEnv
Loại: boolean
Giá trị mặc định: true
Đặt thành false
nếu bạn không muốn mở rộng biến môi trường khi cung cấp thuộc tính env
.
Execa cũng chấp nhận các tùy chọn dưới đây giống với các tùy chọn cho child_process#spawn()/child_process#exec()
cwd
Loại: string | URL
Giá trị mặc định: process.cwd()
Thư mục làm việc hiện tại của tiến trình con.
env
Loại: object
Giá trị mặc định: process.env
Các cặp khóa-giá trị môi trường. Tự động mở rộng từ process.env
. Đặt extendEnv thành false
nếu bạn không muốn điều này.
argv0
Loại: string
Đặt giá trị của argv[0]
gửi đến tiến trình con một cách rõ ràng. Nếu không được chỉ định, nó sẽ được đặt thành file
.
stdio
Loại: string | string[]
Giá trị mặc định: pipe
Cấu hình stdio của tiến trình con.
serialization
Loại: string
Giá trị mặc định: 'json'
Chỉ định loại chuỗi hóa được sử dụng để gửi tin nhắn giữa các tiến trình khi sử dụng tùy chọn stdio: ‘ipc’ hoặc execaNode(): – json
: Sử dụng JSON.stringify()
và JSON.parse()
. – advanced
: Sử dụng v8.serialize()
detached
Loại: boolean
Chuẩn bị cho tiến trình con để chạy độc lập với tiến trình cha của nó. Hành vi cụ thể depends on the platform.
uid
Loại: number
Đặt định danh người dùng của quá trình.
gid
Loại: number
Đặt định danh nhóm của quá trình.
shell
Loại: boolean | string
Giá trị mặc định: false
Nếu là true
, chạy file
trong một shell. Sử dụng /bin/sh
trên UNIX và cmd.exe
trên Windows. Một shell khác có thể được chỉ định dưới dạng một chuỗi. Shell này nên hiểu switch -c
trên UNIX hoặc /d /s /c
trên Windows.
Chúng tôi không khuyến nghị sử dụng tùy chọn này vì nó:
- không đa nền tảng, khuyến khích cú pháp cụ thể cho shell.
- chậm hơn, do việc giải thích thêm của shell.
- không an toàn, có thể cho phép tiêm lệnh.
encoding
Loại: string | null
Giá trị mặc định: utf8
Chỉ định mã ký tự được sử dụng để giải mã đầu ra stdout
và stderr
. Nếu đặt thành null
, thì stdout
và stderr
sẽ là một Buffer
thay vì một chuỗi.
timeout
Loại: number
Giá trị mặc định: 0
Nếu thời gian chờ lớn hơn 0
, tiến trình cha sẽ gửi tín hiệu được xác định bởi thuộc tính killSignal
(mặc định là SIGTERM
) nếu tiến trình con chạy lâu hơn thời gian chờ tính bằng mili giây.
maxBuffer
Loại: number
Giá trị mặc định: 100_000_000
(100 MB)
Số lượng dữ liệu tối đa trong byte cho phép trên stdout
hoặc stderr
.
killSignal
Loại: string | number
Giá trị mặc định: SIGTERM
Giá trị tín hiệu sẽ được sử dụng khi tiến trình con được kết thúc.
signal
Loại: AbortSignal
Bạn có thể hủy bỏ tiến trình con bằng cách sử dụng AbortController.
Khi AbortController.abort()
được gọi, .isCanceled trở thành false
.
windowsVerbatimArguments
Loại: boolean
Giá trị mặc định: false
Nếu là true
, không có dấu ngoặc hoặc ký tự thoát trong các đối số trên Windows. Được bỏ qua trên các nền tảng khác. Giá trị này sẽ tự động đặt thành true
khi tùy chọn shell
là true
.
windowsHide
Loại: boolean
Giá trị mặc định: true
Trên Windows, không tạo cửa sổ console mới. Lưu ý rằng điều này cũng ngăn chặn việc CTRL-C
from working trên Windows.
verbose
Loại: boolean
Giá trị mặc định: false
Hiển thị thông tin chi tiết về quá trình trên stderr
trước khi thực hiện nó.
Điều này cũng có thể được kích hoạt bằng cách đặt biến môi trường NODE_DEBUG=execa
trong quá trình hiện tại.
nodePath (Chỉ dành cho_.node()_
)_
Loại: string
Giá trị mặc định: process.execPath
Ứng dụng Node.js được sử dụng để tạo tiến trình con.
nodeOptions (Chỉ dành cho_.node()_
)_
Loại: string[]
Giá trị mặc định: process.execArgv
Danh sách CLI options được truyền cho tiến trình thực thi Node.js.
Mẹo
Thử lại sau khi xảy ra lỗi
Xử lý lỗi một cách trôi chảy bằng cách sử dụng các lần thử lại tự động và đợi lâu theo chuỗi số với gói p-retry:
import pRetry from 'p-retry';
const run = async () => {
const results = await execa('curl', ['-sSL', 'https://sindresorhus.com/unicorn']);
return results;
};
console.log(await pRetry(run, {retries: 5}));
Hủy tiến trình con
import {execa} from 'execa';
const abortController = new AbortController();
const subprocess = execa('node', [], {signal: abortController.signal});
setTimeout(() => {
abortController.abort();
}, 1000);
try {
await subprocess;
} catch (error) {
console.log(subprocess.killed); // true
console.log(error.isCanceled); // true
}
Thực thi tệp nhị phân của gói hiện tại
import {getBinPath} from 'get-bin-path';
const binPath = await getBinPath();
await execa(binPath);
execa
có thể được kết hợp với get-bin-path để thử tệp nhị phân của gói hiện tại. Thay vì cố định đường dẫn đến tệp nhị phân, điều này xác nhận rằng trường bin
trong package.json
được cài đặt đúng cách.
Liên quan
- gulp-execa – Plugin Gulp cho
execa
- nvexeca – Chạy
execa
bằng bất kỳ phiên bản Node.js nào - sudo-prompt – Chạy các lệnh với đặc quyền được nâng cao.
Người duy trì
Chi tiết Tải về:
Tác giả: Sindresorhus
Mã nguồn: https://github.com/sindresorhus/execa
Giấy phép: MIT license