---
description: Run commands with streaming output, error handling, and shell access.
title: Execute commands
image: https://developers.cloudflare.com/og-docs.png
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/sandbox/llms.txt  
> Use this file to discover all available pages before exploring further.

# Execute commands

Last updated Aug 24, 2026|Copy as Markdown|[View as Markdown](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/guides/execute-commands/index.md)|[Agent setup](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/agent-setup/)

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

Coming soon: Sandbox SDK 1.0

This page documents command execution on today's stable `@cloudflare/sandbox` package.

**Sandbox SDK 1.0** (preview on `@cloudflare/sandbox@next`) uses argv `exec()` and process handles instead of string `exec` / `startProcess` / `execStream`. Refer to [Process execution](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/1-0-preview/processes/), the [Processes API](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/1-0-preview/api/processes/), or [migrate to the preview](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/1-0-preview/migrate/).

## 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.

Note

For **web servers, databases, or services that need to keep running**, use `startProcess()` instead. See the [Background processes guide](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/guides/background-processes/).

## Execute basic commands

Use `exec()` for simple commands that complete quickly:

```js
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
```

```plaintext
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:

```js
// 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");
```

```plaintext
// 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)

```js
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;
}
```

```plaintext
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:

```js
// 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");
```

```plaintext
// 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

```js
// 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");
```

```plaintext
// 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');
```

## Timeouts

Set a maximum execution time for commands to prevent long-running operations from blocking indefinitely.

### Per-command timeout

Pass `timeout` in the options to set a timeout for a single command:

```js
const result = await sandbox.exec("npm run build", {
	timeout: 30000, // 30 seconds
});
```

```plaintext
const result = await sandbox.exec('npm run build', {
  timeout: 30000 // 30 seconds
});
```

### Session-level timeout

Set a default timeout for all commands in a session with `commandTimeoutMs`:

```js
const session = await sandbox.createSession({
	commandTimeoutMs: 10000, // 10s default for all commands
});

await session.exec("npm install"); // Times out after 10s
await session.exec("npm run build"); // Times out after 10s

// Per-command timeout overrides the session default
await session.exec("npm test", { timeout: 60000 }); // 60s for this command
```

```plaintext
const session = await sandbox.createSession({
  commandTimeoutMs: 10000 // 10s default for all commands
});

await session.exec('npm install');    // Times out after 10s
await session.exec('npm run build');  // Times out after 10s

// Per-command timeout overrides the session default
await session.exec('npm test', { timeout: 60000 }); // 60s for this command
```

### Global timeout

Set the `COMMAND_TIMEOUT_MS` [environment variable](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/configuration/environment-variables/#command%5Ftimeout%5Fms) to define a global default timeout for every `exec()` call across all sessions.

### Timeout precedence

When multiple timeouts are configured, the most specific value wins:

1. **Per-command** `timeout` on `exec()` (highest priority)
2. **Session-level** `commandTimeoutMs` on `createSession()`
3. **Global** `COMMAND_TIMEOUT_MS` environment variable (lowest priority)

If none are set, commands run without a timeout.

### Timeout does not kill the process

Caution

When a command times out, the SDK raises an error and closes the connection. The underlying process **continues running** inside the container. To stop a timed-out process, delete the session with [deleteSession()](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/api/sessions/#deletesession) or destroy the sandbox with [destroy()](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/api/lifecycle/#destroy).

## 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](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/guides/background-processes/) instead
* **Handle errors** \- Check stderr for error details

## Troubleshooting

### Command not found

Verify the command exists in the container:

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

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

### Working directory issues

Use absolute paths or change directory:

```js
// Use absolute path
await sandbox.exec("python /workspace/my-app/script.py");

// Or change directory
await sandbox.exec("cd /workspace/my-app && python script.py");
```

```plaintext
// Use absolute path
await sandbox.exec('python /workspace/my-app/script.py');

// Or change directory
await sandbox.exec('cd /workspace/my-app && python script.py');
```

## Related resources

* [Commands API reference](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/api/commands/) \- Complete method documentation
* [Background processes guide](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/guides/background-processes/) \- Managing long-running processes
* [Streaming output guide](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/guides/streaming-output/) \- Advanced streaming patterns
* [Code Interpreter guide](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/sandbox/guides/code-execution/) \- Higher-level code execution

Was this helpful?

YesNo

## On this page

[![](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://docs-durable-objects-instance-replaced-errors.previews.developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/sandbox/guides/execute-commands/#page","headline":"Execute commands · Cloudflare Sandbox SDK docs","description":"Run commands with streaming output, error handling, and shell access.","url":"https://developers.cloudflare.com/sandbox/guides/execute-commands/","inLanguage":"en","image":"https://developers.cloudflare.com/og-docs.png","dateModified":"2026-08-24","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
```
