命令与进程
以下示例中的 sandbox 来自创建沙箱。
等待执行结果
run() 默认等待命令结束,返回标准输出、标准错误和退出码。
python
result = sandbox.commands.run("uname -a")
print(result.stdout)
print(result.stderr)
print(result.exit_code)js
const result = await sandbox.commands.run("uname -a");
console.log(result.stdout, result.stderr, result.exitCode);命令默认最多等待 60 秒。Python 使用 timeout=120,JS 使用 { timeoutMs: 120000 } 调整等待时间;这不会延长沙箱存活时间。
实时输出
python
result = sandbox.commands.run(
"printf 'step 1\n'; sleep 1; printf 'step 2\n'",
on_stdout=lambda chunk: print(chunk, end=""),
on_stderr=lambda chunk: print(chunk, end=""),
)js
const result = await sandbox.commands.run(
"printf 'step 1\n'; sleep 1; printf 'step 2\n'",
{
onStdout: (chunk) => { process.stdout.write(chunk); },
onStderr: (chunk) => { process.stderr.write(chunk); },
},
);后台运行与输入
后台模式返回进程句柄。需要进程读到输入结束时调用 close_stdin() / closeStdin(),它不是退出终端的命令。
python
process = sandbox.commands.run("cat", background=True, stdin=True)
try:
print("PID:", process.pid)
process.send_stdin("hello\n")
process.close_stdin()
result = process.wait()
print(result.stdout)
finally:
process.disconnect()js
const command = await sandbox.commands.run("cat", {
background: true,
stdin: true,
});
try {
console.log("PID:", command.pid);
await command.sendStdin("hello\n");
await command.closeStdin();
console.log((await command.wait()).stdout);
} finally {
await command.disconnect();
}断开与重连
disconnect() 只断开输出流,不结束远端进程。保存 PID 后,可以通过 sandbox.commands.connect(pid) 重新订阅输出,再调用 wait() 获取退出结果。
重连不会回放断开期间的输出。重要结果应写入沙箱文件,再通过文件接口读取。列出现有进程使用 sandbox.commands.list();结束进程使用句柄的 send_signal("SIGTERM"),JS 对应 sendSignal("SIGTERM")。
非零退出码
非零退出码默认抛出 CommandExitError。需要自行判断时,Python 传入 check=False,JS 传入 { check: false }。
指定执行用户
省略 user 时使用沙箱默认用户。指定的用户须已存在,并有权访问 cwd。
python
result = sandbox.commands.run("id", user="nobody", cwd="/tmp")js
const result = await sandbox.commands.run("id", { user: "nobody", cwd: "/tmp" });不要将未受信任的输入直接拼接到 Shell 命令中。