在沙箱的隔离 container 环境中执行命令并管理后台进程。
执行命令并返回完整结果。
const result = await sandbox.exec(command: string, options?: ExecOptions): Promise<ExecuteResponse>参数:
command- 要执行的命令(可包含参数)options(可选):stream- 启用流式回调(默认:false)onOutput- 实时输出回调:(stream: 'stdout' | 'stderr', data: string) => voidtimeout- 最大执行时间(毫秒)env- 此命令的环境变量:Record<string, string | undefined>cwd- 此命令的工作目录stdin- 传递给命令标准输入的数据(可在无 shell 注入风险的情况下传入任意输入)
返回:带有 success、stdout、stderr、exitCode 的 Promise<ExecuteResponse>
const result = await sandbox.exec("npm run build");
if (result.success) {
console.log("Build output:", result.stdout);
} else {
console.error("Build failed:", result.stderr);
}
// With streaming
await sandbox.exec("npm install", {
stream: true,
onOutput: (stream, data) => console.log(`[${stream}] ${data}`),
});
// With environment variables (undefined values are skipped)
await sandbox.exec("node app.js", {
env: {
NODE_ENV: "production",
PORT: "3000",
DEBUG_MODE: undefined, // Skipped, uses container default or unset
},
});
// Pass input via stdin (no shell injection risks)
const result = await sandbox.exec("cat", {
stdin: "Hello, world!",
});
console.log(result.stdout); // "Hello, world!"
// Process user input safely
const userInput = "user@example.com\nsecret123";
await sandbox.exec("python process_login.py", {
stdin: userInput,
});const result = await sandbox.exec('npm run build');
if (result.success) {
console.log('Build output:', result.stdout);
} else {
console.error('Build failed:', result.stderr);
}
// With streaming
await sandbox.exec('npm install', {
stream: true,
onOutput: (stream, data) => console.log(`[${stream}] ${data}`)
});
// With environment variables (undefined values are skipped)
await sandbox.exec('node app.js', {
env: {
NODE_ENV: 'production',
PORT: '3000',
DEBUG_MODE: undefined // Skipped, uses container default or unset
}
});
// Pass input via stdin (no shell injection risks)
const result = await sandbox.exec('cat', {
stdin: 'Hello, world!'
});
console.log(result.stdout); // "Hello, world!"
// Process user input safely
const userInput = 'user@example.com\nsecret123';
await sandbox.exec('python process_login.py', {
stdin: userInput
});执行命令并返回用于实时处理的 Server-Sent Events 流。
const stream = await sandbox.execStream(command: string, options?: ExecOptions): Promise<ReadableStream>参数:
command- 要执行的命令options- 与exec()相同(包括stdin支持)
返回:发出 ExecEvent 对象(start、stdout、stderr、complete、error)的 Promise<ReadableStream>
import { parseSSEStream } from "@cloudflare/sandbox";
const stream = await sandbox.execStream("npm run build");
for await (const event of parseSSEStream(stream)) {
switch (event.type) {
case "stdout":
console.log("Output:", event.data);
break;
case "complete":
console.log("Exit code:", event.exitCode);
break;
case "error":
console.error("Failed:", event.error);
break;
}
}
// Stream with stdin input
const inputStream = await sandbox.execStream(
'python -c "import sys; print(sys.stdin.read())"',
{
stdin: "Data from Workers!",
},
);
for await (const event of parseSSEStream(inputStream)) {
if (event.type === "stdout") {
console.log("Python received:", event.data);
}
}import { parseSSEStream, type ExecEvent } from '@cloudflare/sandbox';
const stream = await sandbox.execStream('npm run build');
for await (const event of parseSSEStream<ExecEvent>(stream)) {
switch (event.type) {
case 'stdout':
console.log('Output:', event.data);
break;
case 'complete':
console.log('Exit code:', event.exitCode);
break;
case 'error':
console.error('Failed:', event.error);
break;
}
}
// Stream with stdin input
const inputStream = await sandbox.execStream('python -c "import sys; print(sys.stdin.read())"', {
stdin: 'Data from Workers!'
});
for await (const event of parseSSEStream<ExecEvent>(inputStream)) {
if (event.type === 'stdout') {
console.log('Python received:', event.data);
}
}启动长时间运行的后台进程。
const process = await sandbox.startProcess(command: string, options?: ProcessOptions): Promise<Process>参数:
command- 作为后台进程启动的命令options(可选):cwd- 工作目录env- 环境变量:Record<string, string | undefined>stdin- 传递给命令标准输入的数据timeout- 最大执行时间(毫秒)processId- 自定义进程 IDencoding- 输出编码(默认:'utf8')autoCleanup- 沙箱休眠时是否清理进程
返回:Promise<Process> 对象,包含:
id- 唯一进程标识符pid- 系统进程 IDcommand- 正在执行的命令status- 当前状态('running'、'exited'等)kill()- 停止进程getStatus()- 获取当前状态getLogs()- 获取累计日志waitForPort()- 等待进程监听端口waitForLog()- 等待进程输出中出现模式waitForExit()- 等待进程终止并返回退出码
const server = await sandbox.startProcess("python -m http.server 8000");
console.log("Started with PID:", server.pid);
// With custom environment
const app = await sandbox.startProcess("node app.js", {
cwd: "/workspace/my-app",
env: { NODE_ENV: "production", PORT: "3000" },
});
// Start process with stdin input (useful for interactive applications)
const interactive = await sandbox.startProcess("python interactive_app.py", {
stdin: "initial_config\nstart_mode\n",
});const server = await sandbox.startProcess('python -m http.server 8000');
console.log('Started with PID:', server.pid);
// With custom environment
const app = await sandbox.startProcess('node app.js', {
cwd: '/workspace/my-app',
env: { NODE_ENV: 'production', PORT: '3000' }
});
// Start process with stdin input (useful for interactive applications)
const interactive = await sandbox.startProcess('python interactive_app.py', {
stdin: 'initial_config\nstart_mode\n'
});列出所有正在运行的进程。
const processes = await sandbox.listProcesses(): Promise<ProcessInfo[]>const processes = await sandbox.listProcesses();
for (const proc of processes) {
console.log(`${proc.id}: ${proc.command} (PID ${proc.pid})`);
}const processes = await sandbox.listProcesses();
for (const proc of processes) {
console.log(`${proc.id}: ${proc.command} (PID ${proc.pid})`);
}终止特定进程及其所有子进程。
await sandbox.killProcess(processId: string, signal?: string): Promise<void>参数:
processId- 进程 ID(来自startProcess()或listProcesses())signal- 要发送的信号(默认:"SIGTERM")
将信号发送到整个进程组,确保主进程及其派生的任何子进程都被终止。这可防止父进程被杀死后出现孤儿进程继续运行。
const server = await sandbox.startProcess("python -m http.server 8000");
await sandbox.killProcess(server.id);
// Example with a process that spawns children
const script = await sandbox.startProcess(
'bash -c "sleep 10 & sleep 10 & wait"',
);
// killProcess terminates both sleep commands and the bash process
await sandbox.killProcess(script.id);const server = await sandbox.startProcess('python -m http.server 8000');
await sandbox.killProcess(server.id);
// Example with a process that spawns children
const script = await sandbox.startProcess('bash -c "sleep 10 & sleep 10 & wait"');
// killProcess terminates both sleep commands and the bash process
await sandbox.killProcess(script.id);终止所有正在运行的进程。
await sandbox.killAllProcesses(): Promise<void>await sandbox.killAllProcesses();await sandbox.killAllProcesses();实时流式传输正在运行进程的日志。
const stream = await sandbox.streamProcessLogs(processId: string): Promise<ReadableStream>参数:
processId- 进程 ID
返回:发出 LogEvent 对象的 Promise<ReadableStream>
import { parseSSEStream } from "@cloudflare/sandbox";
const server = await sandbox.startProcess("node server.js");
const logStream = await sandbox.streamProcessLogs(server.id);
for await (const log of parseSSEStream(logStream)) {
console.log(`[${log.timestamp}] ${log.data}`);
if (log.data.includes("Server started")) break;
}import { parseSSEStream, type LogEvent } from '@cloudflare/sandbox';
const server = await sandbox.startProcess('node server.js');
const logStream = await sandbox.streamProcessLogs(server.id);
for await (const log of parseSSEStream<LogEvent>(logStream)) {
console.log(`[${log.timestamp}] ${log.data}`);
if (log.data.includes('Server started')) break;
}获取进程的累计日志。
const logs = await sandbox.getProcessLogs(processId: string): Promise<string>参数:
processId- 进程 ID
返回:包含所有累计输出的 Promise<string>
const server = await sandbox.startProcess("node server.js");
await new Promise((resolve) => setTimeout(resolve, 5000));
const logs = await sandbox.getProcessLogs(server.id);
console.log("Server logs:", logs);const server = await sandbox.startProcess('node server.js');
await new Promise(resolve => setTimeout(resolve, 5000));
const logs = await sandbox.getProcessLogs(server.id);
console.log('Server logs:', logs);所有命令执行方法都支持通过 stdin 选项向命令的标准输入传递数据。这可以在无 shell 注入风险的情况下安全处理用户输入。
当你提供 stdin 选项时:
- 输入数据会写入 container 内的临时文件
- 命令通过其标准输入流接收这些数据
- 执行后自动清理临时文件
此方法可防止将用户数据直接嵌入命令时可能发生的 shell 注入攻击。
// Safe: User input goes through stdin, not shell parsing
const userInput = "user@domain.com; rm -rf /";
const result = await sandbox.exec("python validate_email.py", {
stdin: userInput,
});
// Instead of unsafe: `python validate_email.py "${userInput}"`
// which could execute the embedded `rm -rf /` command// Safe: User input goes through stdin, not shell parsing
const userInput = 'user@domain.com; rm -rf /';
const result = await sandbox.exec('python validate_email.py', {
stdin: userInput
});
// Instead of unsafe: `python validate_email.py "${userInput}"`
// which could execute the embedded `rm -rf /` command处理表单数据:
const formData = JSON.stringify({
username: "john_doe",
email: "john@example.com",
});
const result = await sandbox.exec("python process_form.py", {
stdin: formData,
});const formData = JSON.stringify({
username: 'john_doe',
email: 'john@example.com'
});
const result = await sandbox.exec('python process_form.py', {
stdin: formData
});交互式命令行工具:
// Simulate user responses to prompts
const responses = "yes\nmy-app\n1.0.0\n";
const result = await sandbox.exec("npm init", {
stdin: responses,
});// Simulate user responses to prompts
const responses = 'yes\nmy-app\n1.0.0\n';
const result = await sandbox.exec('npm init', {
stdin: responses
});数据转换:
const csvData = "name,age,city\nJohn,30,NYC\nJane,25,LA";
const result = await sandbox.exec("python csv_processor.py", {
stdin: csvData,
});
console.log("Processed data:", result.stdout);const csvData = 'name,age,city\nJohn,30,NYC\nJane,25,LA';
const result = await sandbox.exec('python csv_processor.py', {
stdin: csvData
});
console.log('Processed data:', result.stdout);startProcess() 返回的 Process 对象包含用于等待进程就绪后再继续的方法。
等待进程监听端口。
await process.waitForPort(port: number, options?: WaitForPortOptions): Promise<void>参数:
port- 要检查的端口号options(可选):mode- 检查模式:'http'(默认)或'tcp'timeout- 最大等待时间(毫秒)interval- 检查间隔(毫秒,默认:100)path- 要检查的 HTTP 路径(默认:'/',仅 HTTP 模式)status- 期望的 HTTP 状态范围(默认:{ min: 200, max: 399 },仅 HTTP 模式)
**HTTP 模式(默认)**发起 HTTP GET 请求并检查响应状态:
const server = await sandbox.startProcess("node server.js");
// Wait for server to be ready (HTTP mode)
await server.waitForPort(3000);
// Check specific endpoint and status
await server.waitForPort(8080, {
path: "/health",
status: { min: 200, max: 299 },
timeout: 30000,
});const server = await sandbox.startProcess('node server.js');
// Wait for server to be ready (HTTP mode)
await server.waitForPort(3000);
// Check specific endpoint and status
await server.waitForPort(8080, {
path: '/health',
status: { min: 200, max: 299 },
timeout: 30000
});TCP 模式检查端口是否接受连接:
const db = await sandbox.startProcess("redis-server");
// Wait for database to accept connections
await db.waitForPort(6379, {
mode: "tcp",
timeout: 10000,
});const db = await sandbox.startProcess('redis-server');
// Wait for database to accept connections
await db.waitForPort(6379, {
mode: 'tcp',
timeout: 10000
});抛出:
ProcessReadyTimeoutError- 若端口在超时内未就绪ProcessExitedBeforeReadyError- 若进程在就绪前退出
等待进程输出中出现某个模式。
const result = await process.waitForLog(pattern: string | RegExp, timeout?: number): Promise<WaitForLogResult>参数:
pattern- 在 stdout/stderr 中匹配的字符串或 RegExptimeout- 最大等待时间(毫秒,可选)
返回:Promise<WaitForLogResult>,包含:
line- 匹配的输出行matches- 捕获组数组(用于 RegExp 模式)
const server = await sandbox.startProcess("node server.js");
// Wait for string pattern
const result = await server.waitForLog("Server listening");
console.log("Ready:", result.line);
// Wait for RegExp with capture groups
const result = await server.waitForLog(/Server listening on port (\d+)/);
console.log("Port:", result.matches[1]); // Extracted port number
// With timeout
await server.waitForLog("Ready", 30000);const server = await sandbox.startProcess('node server.js');
// Wait for string pattern
const result = await server.waitForLog('Server listening');
console.log('Ready:', result.line);
// Wait for RegExp with capture groups
const result = await server.waitForLog(/Server listening on port (\d+)/);
console.log('Port:', result.matches[1]); // Extracted port number
// With timeout
await server.waitForLog('Ready', 30000);抛出:
ProcessReadyTimeoutError- 若在超时内未找到模式ProcessExitedBeforeReadyError- 若进程在模式出现前退出
等待进程终止并返回退出码。
const result = await process.waitForExit(timeout?: number): Promise<WaitForExitResult>参数:
timeout- 最大等待时间(毫秒,可选)
返回:Promise<WaitForExitResult>,包含:
exitCode- 进程退出码
const build = await sandbox.startProcess("npm run build");
// Wait for build to complete
const result = await build.waitForExit();
console.log("Build finished with exit code:", result.exitCode);
// With timeout
const result = await build.waitForExit(60000); // 60 second timeoutconst build = await sandbox.startProcess('npm run build');
// Wait for build to complete
const result = await build.waitForExit();
console.log('Build finished with exit code:', result.exitCode);
// With timeout
const result = await build.waitForExit(60000); // 60 second timeout抛出:
ProcessReadyTimeoutError- 若进程在超时内未退出