跳至主要內容

建立子程序

概念

  • Deno 能夠透過 Deno.Command 產生子程序。
  • 產生子程序需要 --allow-run 權限。
  • 產生的子程序不會在安全沙箱中執行。
  • 透過 stdinstdoutstderr 串流與子程序溝通。

簡單範例

此範例等同於從命令列執行 'echo hello'

/**
* subprocess_simple.ts
*/

// define command used to create the subprocess
const command = new Deno.Command(Deno.execPath(), {
args: [
"eval",
"console.log('hello'); console.error('world')",
],
});

// create subprocess and collect output
const { code, stdout, stderr } = await command.output();

console.assert(code === 0);
console.assert("world\n" === new TextDecoder().decode(stderr));
console.log(new TextDecoder().decode(stdout));

執行

$ deno run --allow-run --allow-read ./subprocess_simple.ts
hello

安全性

建立子程序需要 --allow-run 權限。請注意,子程序並非在 Deno 沙盒中執行,因此擁有與您從命令列執行命令時相同的權限。

與子程序溝通

預設情況下,當您使用 Deno.Command() 時,子程序會繼承父程序的 stdinstdoutstderr。如果您想與已啟動的子程序溝通,您必須使用 "piped" 選項。

導管至檔案

此範例等同於在 bash 中執行 yes &> ./process_output

/**
* subprocess_piping_to_file.ts
*/

import {
mergeReadableStreams,
} from "https://deno.land/std@0.220.0/streams/merge_readable_streams.ts";

// create the file to attach the process to
const file = await Deno.open("./process_output.txt", {
read: true,
write: true,
create: true,
});

// start the process
const command = new Deno.Command("yes", {
stdout: "piped",
stderr: "piped",
});

const process = command.spawn();

// example of combining stdout and stderr while sending to a file
const joined = mergeReadableStreams(
process.stdout,
process.stderr,
);

// returns a promise that resolves when the process is killed/closed
joined.pipeTo(file.writable).then(() => console.log("pipe join done"));

// manually stop process "yes" will never end on its own
setTimeout(() => {
process.kill();
}, 100);

執行

$ deno run --allow-run --allow-read --allow-write ./subprocess_piping_to_file.ts