サンドボックスの分離されたコンテナ環境でコマンドを実行し、バックグラウンドプロセスを管理します。
コマンドを実行し、完了した結果を返します。
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- コマンドの標準入力へ渡すデータ(シェルインジェクションのリスクなしで任意の入力を渡せます)
戻り値: 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 オプションでコマンドの標準入力へデータを渡せます。シェルインジェクションのリスクなしで、ユーザー入力を安全に処理できます。
stdin オプションを指定すると、次のように動作します。
- 入力データをコンテナ内の一時ファイルへ書き込みます
- コマンドは標準入力ストリームからこのデータを受け取ります
- 実行後、一時ファイルは自動的に削除されます
この方法により、ユーザーデータをコマンドへ直接埋め込んだときに起きるシェルインジェクション攻撃を防げます。
// 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- タイムアウトまでにプロセスが終了しない場合
- バックグラウンドプロセスガイド - 長時間実行するプロセスの管理
- Files API - ファイル操作