跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

更改命令调用

最后更新 查看 MarkdownAgent 设置

将 0.12 命令调用替换为容器上的 exec()。在 Sandbox SDK 0.12 中,exec() 在从 /workspace 启动的长期 bash 会话中运行每条命令字符串。在 1.0 中,每次调用启动一个进程,一次调用不会把任何内容带到下一次。

开始之前

你的 1.0 类已替换 0.12 Sandbox 类,并具有 替换 Sandbox 类 中的 container getter、ensureRunning() 方法和 ENV 常量。在每个运行命令的方法开头调用 ensureRunning()。

本页替换 exec()、execStream()、createSession()、getSession()、deleteSession(),以及 timeout 和 commandTimeoutMs 选项。有关文件调用,请参阅 更改文件调用。有关 startProcess(),请参阅 迁移后台进程。

运行命令

将命令作为参数数组传入,并带上 0.12 提供给它的工作目录和变量:

src/index.ts (0.12)ts
const result = await sandbox.exec("npm test");

if (!result.success) {
    console.error(result.stderr);
}
src/index.ts (1.0)ts
const process = await this.container.exec(["npm", "test"], {
    cwd: "/workspace",
    env: ENV,
});
const result = await process.output();

if (result.exitCode !== 0) {
    console.error(new TextDecoder().decode(result.stderr));
}

exec() 从 / 启动,即使镜像设置了 WORKDIR。它不会继承 start() 设置的变量,PATH 除外。output() 等待进程退出,并以字节形式返回其输出。与 0.12 一样,非零退出码不会抛出错误。

exec() 在不使用 shell 的情况下运行命令。对于管道、重定向和变量,请用 bash 运行 0.12 字符串:

src/index.tsts
const process = await this.container.exec(
    ["bash", "-c", "npm test 2>&1 | tee /tmp/test.log"],
    { cwd: "/workspace", env: ENV },
);

当可执行文件不存在时,exec() 会抛出类似 Command `npm` was not found in the container 的错误。0.12 的 bash 则返回退出码 127。通过 bash -c 运行的命令仍会返回 127。

流式输出

要替换 execStream(),或带有 stream: true 和 onOutput 的 exec(),请将进程的 stdout 作为响应正文返回:

src/index.ts (0.12)ts
const stream = await sandbox.execStream("npm test");

return new Response(stream, {
    headers: { "Content-Type": "text/event-stream" },
});
src/index.ts (1.0)ts
const process = await this.container.exec(["npm", "test"], {
    cwd: "/workspace",
    env: ENV,
    stderr: "combined",
});

return new Response(process.stdout, {
    headers: { "Content-Type": "text/event-stream" },
});

stderr: "combined" 会在同一流中发送标准错误。当命令几乎同时写入两个流时,行可能会乱序到达。要保持顺序,请改为在 shell 中重定向,例如 ["sh", "-c", "npm test 2>&1"]。保持 Content-Type: text/event-stream。使用其他内容类型时,响应可能在进程退出时一次性到达。

0.12 发送由 parseSSEStream() 解码的 JSON 事件。1.0 正文保存命令的输出。请改用 fetch() 和 stream reader 读取,而不是 EventSource。要将每行作为 server-sent event 发送,请参阅 流式命令输出。

替换会话

0.12 会话会在调用之间保留工作目录和变量。将它们保存在对象中,并传给每次调用:

src/index.ts (0.12)ts
const build = await sandbox.createSession({
    cwd: "/workspace/app",
    env: { CI: "1" },
});

await build.exec("npm ci");
await build.exec("npm test");
src/index.ts (1.0)ts
const build = { cwd: "/workspace/app", env: { ...ENV, CI: "1" } };

const install = await this.container.exec(["npm", "ci"], build);
await install.exitCode;

const test = await this.container.exec(["npm", "test"], build);
const result = await test.output();

exec() 在进程启动时 resolve,因此在下一步之前请等待 exitCode。

在 0.12 中,一次 exec() 调用中的 cd 或 export 会带到下一次调用,包括默认会话。在 1.0 中,它只持续到该命令退出。将相互依赖的步骤放在一条命令中运行,例如 ["bash", "-c", "cd app && npm ci && npm test"]。

ExecutionSession 方法与顶层方法的对应关系相同。删除 deleteSession(),因为没有需要删除的内容。0.12 接受但忽略 isolation 选项,因此同一 sandbox 中的会话始终共享进程和文件。若要隔离两个会话的工作,请为它们分别指定 sandbox 名称。

替换超时

使用 GNU coreutils timeout 启动命令;它会停止命令及其启动的进程,这些进程必须仍位于其进程组中:

src/index.ts (0.12)ts
const result = await sandbox.exec("npm test", { timeout: 60_000 });
src/index.ts (1.0)ts
const process = await this.container.exec(
    ["timeout", "--kill-after=5", "60", "bash", "-c", "npm test"],
    { cwd: "/workspace", env: ENV },
);
const result = await process.output();
// 124 or 137 means the command ran longer than 60 seconds
const timedOut = result.exitCode === 124 || result.exitCode === 137;

0.12 会抛出消息为 Command timeout after 60000ms 的 CommandError,而命令会继续运行。在 1.0 中,超时的命令会停止,因此出错后无法再更改文件。

要从代码中取消命令,请传入 AbortSignal。如何清除其计时器,请参阅 exec()。

检查命令

从类上的方法运行带选项和不带选项的命令:

src/index.tsts
const command = [
    "sh",
    "-c",
    'echo "pwd=$(pwd) NODE_ENV=${NODE_ENV:-unset}"',
];

const bare = await this.container.exec(command);
const withOptions = await this.container.exec(command, {
    cwd: "/workspace",
    env: ENV,
});

bare 的输出显示默认值,withOptions 的输出显示 0.12 提供给每条命令的内容:

pwd=/ NODE_ENV=unset
pwd=/workspace NODE_ENV=test

相关资源

这篇文档对您有帮助吗?