Commands·续

if (log.data.includes("Server started")) break; }


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

getProcessLogs()

Get accumulated logs from a process.

const logs = await sandbox.getProcessLogs(processId: string): Promise<string>

Parameters:

  • processId - The process ID

Returns: Promise<string> with all accumulated output

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);

Standard input (stdin)

All command execution methods support passing data to a command's standard input via the stdin option. This enables secure processing of user input without shell injection risks.

How stdin works

When you provide the stdin option:

  1. The input data is written to a temporary file inside the container
  2. The command receives this data through its standard input stream
  3. The temporary file is automatically cleaned up after execution

This approach prevents shell injection attacks that could occur when embedding user data directly in commands.

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

Common patterns

Processing form data:

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
});

Interactive command-line tools:

// 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
});

Data transformation:

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);

Process readiness methods

The Process object returned by startProcess() includes methods to wait for the process to be ready before proceeding.

process.waitForPort()

Wait for a process to listen on a port.

await process.waitForPort(port: number, options?: WaitForPortOptions): Promise&lt;void>

Parameters:

  • port - The port number to check
  • options (optional):
  • mode - Check mode: 'http' (default) or 'tcp'
  • timeout - Maximum wait time in milliseconds
  • interval - Check interval in milliseconds (default: 100)
  • path - HTTP path to check (default: '/', HTTP mode only)
  • status - Expected HTTP status range (default: { min: 200, max: 399 }, HTTP mode only)

HTTP mode (default) makes an HTTP GET request and checks the response status:

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 mode checks if the port accepts connections:

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
});

Throws:

  • ProcessReadyTimeoutError - If port does not become ready within timeout
  • ProcessExitedBeforeReadyError - If process exits before becoming ready

process.waitForLog()

Wait for a pattern to appear in process output.

const result = await process.waitForLog(pattern: string | RegExp, timeout?: number): Promise&lt;WaitForLogResult>

Parameters:

  • pattern - String or RegExp to match in stdout/stderr
  • timeout - Maximum wait time in milliseconds (optional)

Returns: Promise<WaitForLogResult> with:

  • line - The matching line of output
  • matches - Array of capture groups (for RegExp patterns)
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);

Throws:

  • ProcessReadyTimeoutError - If pattern is not found within timeout
  • ProcessExitedBeforeReadyError - If process exits before pattern appears

process.waitForExit()

Wait for a process to terminate and return the exit code.

const result = await process.waitForExit(timeout?: number): Promise&lt;WaitForExitResult>

Parameters:

  • timeout - Maximum wait time in milliseconds (optional)

Returns: Promise<WaitForExitResult> with:

  • exitCode - The process exit code
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 timeout
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 timeout

Throws:

  • ProcessReadyTimeoutError - If process does not exit within timeout

Was this helpful?

YesNo

On this page

Commands·续 - 图1Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/sandbox/sdk/api/commands/#page","headline":"Commands","description":"Execute commands and manage background processes in Sandbox SDK 0.x containers.","url":"https://developers.cloudflare.com/sandbox/sdk/api/commands/","inLanguage":"en","image":"https://developers.cloudflare.com/sandbox/sdk/api/commands/og.png?v=ec1a4ee4addf46c4","dateModified":"2026-09-30","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/"}}


description: Monitor sandbox filesystem changes in real-time using the Sandbox SDK 0.x watch API. title: File watching image: https://developers.cloudflare.com/sandbox/sdk/api/file-watching/og.png?v=f026b4444a06c4d1


Skip to 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.