Skip to content
Cloudflare Docs

Execute commands

This guide shows you how to execute commands in the sandbox, handle output, and manage errors effectively.

Choose the right method

The SDK provides multiple approaches for running commands:

  • exec() - Run a command and wait for complete result. Best for one-time commands like builds, installations, and scripts.
  • execStream() - Stream output in real-time. Best for long-running commands where you need immediate feedback.
  • startProcess() - Start a background process. Best for web servers, databases, and services that need to keep running.

Execute basic commands

Use exec() for simple commands that complete quickly:

JavaScript
import { getSandbox } from "@cloudflare/sandbox";
const sandbox = getSandbox(env.Sandbox, "my-sandbox");
// Execute a single command
const result = await sandbox.exec("python --version");
console.log(result.stdout); // "Python 3.11.0"
console.log(result.exitCode); // 0
console.log(result.success); // true

Pass arguments safely

When passing user input or dynamic values, avoid string interpolation to prevent injection attacks:

JavaScript
// Unsafe - vulnerable to injection
const filename = userInput;
await sandbox.exec(`cat ${filename}`);
// Safe - use proper escaping or validation
const safeFilename = filename.replace(/[^a-zA-Z0-9_.-]/g, "");
await sandbox.exec(`cat ${safeFilename}`);
// Better - write to file and execute
await sandbox.writeFile("/tmp/input.txt", userInput);
await sandbox.exec("python process.py /tmp/input.txt");

Handle errors

Commands can fail in two ways:

  1. Non-zero exit code - Command ran but failed (result.success === false)
  2. Execution error - Command couldn't start (throws exception)
JavaScript
try {
const result = await sandbox.exec("python analyze.py");
if (!result.success) {
// Command failed (non-zero exit code)
console.error("Analysis failed:", result.stderr);
console.log("Exit code:", result.exitCode);
// Handle specific exit codes
if (result.exitCode === 1) {
throw new Error("Invalid input data");
} else if (result.exitCode === 2) {
throw new Error("Missing dependencies");
}
}
// Success - process output
return JSON.parse(result.stdout);
} catch (error) {
// Execution error (couldn't start command)
console.error("Execution failed:", error.message);
throw error;
}

Execute shell commands

The sandbox supports shell features like pipes, redirects, and chaining:

JavaScript
// Pipes and filters
const result = await sandbox.exec('ls -la | grep ".py" | wc -l');
console.log("Python files:", result.stdout.trim());
// Output redirection
await sandbox.exec("python generate.py > output.txt 2> errors.txt");
// Multiple commands
await sandbox.exec("cd /workspace && npm install && npm test");

Execute Python scripts

JavaScript
// Run inline Python
const result = await sandbox.exec('python -c "print(sum([1, 2, 3, 4, 5]))"');
console.log("Sum:", result.stdout.trim()); // "15"
// Run a script file
await sandbox.writeFile(
"/workspace/analyze.py",
`
import sys
print(f"Argument: {sys.argv[1]}")
`,
);
await sandbox.exec("python /workspace/analyze.py data.csv");

Use per-command environment variables

Set environment variables for a single command without affecting the session:

JavaScript
// Environment variables scoped to this command only
const result = await sandbox.exec("echo $API_KEY", {
env: { API_KEY: "secret-key-123" },
});
console.log(result.stdout); // "secret-key-123"
// Next command does not have API_KEY
const verify = await sandbox.exec("echo $API_KEY");
console.log(verify.stdout); // "" (empty)

Per-command environment variables:

  • Do not persist in the session
  • Override session-level variables if both are set
  • Are isolated from other concurrent commands
  • Are cleaned up automatically after the command completes

Override working directory

Override the working directory for a single command:

JavaScript
// Execute in a specific directory
const result = await sandbox.exec("pwd", {
cwd: "/workspace/my-project",
});
console.log(result.stdout); // "/workspace/my-project"
// Session working directory unchanged
const verify = await sandbox.exec("pwd");
console.log(verify.stdout); // "/workspace" (default)

Combining cwd and env for complex workflows:

JavaScript
// Run tests in a specific directory with custom environment
await sandbox.exec("npm test", {
cwd: "/workspace/api",
env: {
NODE_ENV: "test",
DATABASE_URL: "sqlite::memory:",
LOG_LEVEL: "debug",
},
});

Best practices

  • Check exit codes - Always verify result.success and result.exitCode
  • Validate inputs - Escape or validate user input to prevent injection
  • Use streaming - For long operations, use execStream() for real-time feedback
  • Use background processes - For services that need to keep running (web servers, databases), use the Background processes guide instead
  • Handle errors - Check stderr for error details

Troubleshooting

Command not found

Verify the command exists in the container:

JavaScript
const check = await sandbox.exec("which python3");
if (!check.success) {
console.error("python3 not found");
}

Working directory issues

Use the cwd option for cleaner code, or use absolute paths:

JavaScript
// Best: Use cwd option
await sandbox.exec("python script.py", {
cwd: "/workspace/my-app",
});
// Alternative: Use absolute path
await sandbox.exec("python /workspace/my-app/script.py");
// Alternative: Change directory inline
await sandbox.exec("cd /workspace/my-app && python script.py");