首页 > 解决方案 > 来自子进程的流标准输出

问题描述

我在 Deno 中将 Docker 构建作为子进程运行,并希望将标准输出流式传输到父标准输出 (Deno.stdout),以便立即输出。

我怎样才能做到这一点?

目前我有以下内容,但在子进程完成之前它不会输出任何内容。

const p = Deno.run({
  cmd: ['docker', 'build', '.'],
  stdout: 'piped'
});

const stdout = await p.output();
await Deno.stdout.write(stdout);

标签: deno

解决方案


你就在不远处;您只需要在等待过程之前启动输出管道的过程。您还可以进行一些其他优化,例如使用Deno.copy管道将子进程的输出传输到主进程的标准输出,而无需在内存中复制内容。

import { copy } from "https://deno.land/std@0.104.0/io/util.ts";

const cat = Deno.run({
  cmd: ["docker", "build", "--no-cache", ".", "-t", "foobar:latest"],
  cwd: "/path/to/your/project",
  stdout: "piped",
  stderr: "piped",
});

copy(cat.stdout, Deno.stdout);
copy(cat.stderr, Deno.stderr);

await cat.status();
console.log("Done!");

如果你想在每一行前面加上它来自的进程的名称(当你有多个子进程运行时很有用,你可以创建一个简单的函数,使用 std lib 的readLines函数和文本编码器来做到这一点

import { readLines } from "https://deno.land/std@0.104.0/io/mod.ts";
import { writeAll } from "https://deno.land/std@0.104.0/io/util.ts";

async function pipeThrough(
  prefix: string,
  reader: Deno.Reader,
  writer: Deno.Writer,
) {
  const encoder = new TextEncoder();
  for await (const line of readLines(reader)) {
    await writeAll(writer, encoder.encode(`[${prefix}] ${line}\n`));
  }
}

const cat = Deno.run({
  cmd: ["docker", "build", "--no-cache", ".", "-t", "foobar:latest"],
  cwd: "/path/to/your/project",
  stdout: "piped",
  stderr: "piped",
});

pipeThrough("docker", cat.stdout, Deno.stdout);
pipeThrough("docker", cat.stderr, Deno.stderr);
await cat.status();
console.log("Done!");

推荐阅读