执行代码与命令
在沙箱中前台 / 后台运行命令,流式获取输出,向进程写入 stdin,并管理运行中的进程。
沙箱内是一套完整的 Ubuntu 24.04 环境,所有代码执行都通过 sandbox.commands 完成。没有针对某种语言的专用 API——无论 Python、Node.js 还是任意二进制,都用 commands.run(...) 跑一条 shell 命令;能跑哪些语言取决于模板镜像里预装了什么。
前台执行
run(cmd) 同步等待命令结束,返回包含 stdout、stderr、exitCode 的命令结果:
const res = await sandbox.commands.run('python3 -c "print(1 + 1)"');
console.log(res.stdout); // "2\n"
console.log(res.stderr); // ""
console.log(res.exitCode); // 0res = sandbox.commands.run('python3 -c "print(1 + 1)"')
print(res.stdout) # "2\n"
print(res.stderr) # ""
print(res.exit_code) # 0res, err := sandbox.Commands.Run(ctx, `python3 -c "print(1 + 1)"`, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Stdout) // "2\n"
fmt.Println(res.Stderr) // ""
fmt.Println(res.ExitCode) // 0# 默认实时流式输出;加 --json 拿单个结果对象
tensor-box sandbox exec "$sbx" 'python3 -c "print(1 + 1)"'
tensor-box sandbox exec "$sbx" 'python3 -c "print(1 + 1)"' --json常用选项
const res = await sandbox.commands.run('npm test', {
cwd: '/home/user/project', // 工作目录
envs: { NODE_ENV: 'test' }, // 环境变量
user: 'user', // 以哪个用户运行(默认 "user")
timeoutMs: 120_000, // 命令超时
});res = sandbox.commands.run(
"npm test",
cwd="/home/user/project", # 工作目录
envs={"NODE_ENV": "test"}, # 环境变量
user="user", # 以哪个用户运行(默认 "user")
timeout_ms=120_000, # 命令超时
)res, err := sandbox.Commands.Run(ctx, "npm test", &tensorbox.RunOptions{
Cwd: "/home/user/project", // 工作目录
Envs: map[string]string{"NODE_ENV": "test"}, // 环境变量
User: "user", // 以哪个用户运行(默认 "user")
Timeout: 120 * time.Second, // 命令超时
})tensor-box sandbox exec "$sbx" "npm test" \
--cwd /home/user/project \
--env NODE_ENV=test \
--user user \
--timeout-ms 120000commands.run 接收的是 shell 命令字符串,因此可以自由使用管道、&&、重定向等。要安装依赖、切换目录后执行等,串成一条命令即可:apt-get update && apt-get install -y ffmpeg。
后台执行
后台启动命令会立即返回一个 CommandHandle,命令在后台继续运行:
const handle = await sandbox.commands.run('python3 server.py', {
background: true,
});
console.log('pid:', handle.pid);
// 需要时等待它结束,拿到最终结果
const result = await handle.wait();
// 或者直接杀掉
await handle.kill();
// 只想断开句柄、让进程继续跑:
handle.disconnect();CommandHandle 提供 pid、wait()(等待结束并返回结果)、kill()、disconnect()(断开但不杀进程)。
handle = sandbox.commands.run("python3 server.py", background=True)
print("pid:", handle.pid)
# 需要时等待它结束,拿到最终结果
result = handle.wait()
# 或者直接杀掉
handle.kill()后台句柄提供 pid、wait()(等待结束并返回结果)、kill()。
handle, err := sandbox.Commands.RunBackground(ctx, "python3 server.py", nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("pid:", handle.PID)
// 需要时等待它结束,拿到最终结果
result, _ := handle.Wait(ctx)
// 或者直接杀掉
handle.Kill(ctx)
// 只想断开句柄、让进程继续跑:
handle.Disconnect()Go 把 TS 的 run(cmd, {background}) 重载拆成 Run(同步)和 RunBackground(返回 *CommandHandle,含 Wait/Kill/Disconnect)。
# --background 立即返回 pid,不等待命令结束
tensor-box sandbox exec "$sbx" "python3 server.py" --background流式获取输出
无论前台还是后台,传入 onStdout / onStderr 回调即可实时接收输出(底层走 SSE / WebSocket 流):
await sandbox.commands.run('pip install numpy pandas', {
onStdout: (data) => process.stdout.write(data),
onStderr: (data) => process.stderr.write(data),
});
// 后台长任务同样可以边跑边流式回传
const handle = await sandbox.commands.run('tail -f /var/log/app.log', {
background: true,
onStdout: (line) => console.log('[app]', line),
});
// ... 之后
await handle.kill();sandbox.commands.run(
"pip install numpy pandas",
on_stdout=lambda data: print(data, end=""),
on_stderr=lambda data: print(data, end=""),
)
# 后台长任务同样可以边跑边流式回传
handle = sandbox.commands.run(
"tail -f /var/log/app.log",
background=True,
on_stdout=lambda line: print("[app]", line, end=""),
)
# ... 之后
handle.kill()_, err := sandbox.Commands.Run(ctx, "pip install numpy pandas", &tensorbox.RunOptions{
OnStdout: func(s string) { fmt.Print(s) },
OnStderr: func(s string) { fmt.Fprint(os.Stderr, s) },
})
// 后台长任务同样可以边跑边流式回传
handle, _ := sandbox.Commands.RunBackground(ctx, "tail -f /var/log/app.log",
&tensorbox.RunOptions{OnStdout: func(line string) { fmt.Print("[app] ", line) }})
// ... 之后
handle.Kill(ctx)# exec 默认就是实时流式输出 stdout / stderr,无需额外参数
tensor-box sandbox exec "$sbx" "pip install numpy pandas"后台流式的 stderr 注意:后台进程走进程流 WebSocket,guest 端把 stdout 和 stderr 都标记为 type:"output",因此后台模式下每个 chunk 都到 onStdout,onStderr 不会触发。需要区分 stdout / stderr 时用同步 run()(SSE 端点会分别发 stdout / stderr 事件)。
向 stdin 写入
对一个已知 PID 的进程写入标准输入:
const handle = await sandbox.commands.run('cat', { background: true });
await sandbox.commands.sendStdin(handle.pid, 'hello\n');handle = sandbox.commands.run("cat", background=True)
sandbox.commands.send_stdin(handle.pid, "hello\n")handle, _ := sandbox.Commands.RunBackground(ctx, "cat", nil)
sandbox.Commands.SendStdin(ctx, handle.PID, "hello\n")进程管理
// 列出当前所有进程
const procs = await sandbox.commands.list();
// [{ processId, pid, cmd, status, exitCode }, ...]
// 连接到一个已在运行的进程,拿回句柄
const handle = await sandbox.commands.connect(somePid);
const result = await handle.wait();
// 按 PID 杀进程
await sandbox.commands.kill(somePid);# 列出当前所有进程
procs = sandbox.commands.list()
# [ProcessInfo(process_id, pid, cmd, status, exit_code), ...]
# 连接到一个已在运行的进程,拿回句柄
handle = sandbox.commands.connect(some_pid)
result = handle.wait()
# 按 PID 杀进程
sandbox.commands.kill(some_pid)// 列出当前所有进程
procs, _ := sandbox.Commands.List(ctx)
// []ProcessEntry{ {ProcessID, PID, Cmd, Status, ExitCode}, ... }
// 连接到一个已在运行的进程,拿回句柄
handle, _ := sandbox.Commands.Connect(ctx, somePID)
result, _ := handle.Wait(ctx)
// 按 PID 杀进程
sandbox.Commands.Kill(ctx, somePID)方法一览
| 方法(TS / Python / Go) | 说明 |
|---|---|
commands.run / commands.run / Commands.Run | 前台执行,返回结果 { stdout, stderr, exitCode } |
run(cmd, { background }) / run(..., background=True) / Commands.RunBackground | 后台执行,返回句柄 { pid, wait, kill, disconnect } |
commands.list / commands.list / Commands.List | 列出运行中的进程 |
commands.connect / commands.connect / Commands.Connect | 连接到运行中的进程,返回句柄 |
commands.kill / commands.kill / Commands.Kill | 按 PID 杀进程 |
commands.sendStdin / commands.send_stdin / Commands.SendStdin | 向进程 stdin 写入数据 |
run 的选项:background(仅 TS/Python)、cwd、envs、timeoutMs/timeout_ms/Timeout、user/User、onStdout/on_stdout/OnStdout、onStderr/on_stderr/OnStderr、requestTimeoutMs/request_timeout_ms/RequestTimeout。
需要真正的交互式终端(带 TTY、行编辑、top 等全屏程序)请使用 PTY 终端,而不是 commands.run。CLI 用户可直接 tensor-box sandbox terminal <id> 进入交互式 PTY。