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

# コマンドの実行

> ストリーミング、プロセス制御、エラー処理を備えたサンドボックスでのコマンド実行。

これらの例では、`CWSANDBOX_API_KEY` に設定した CoreWeave API アクセストークンを使用します。Forge の APIキーによる認証については、[はじめに](/ja/products/sandboxes/get-started)を参照してください。CKS の要件については、[配置モード](/ja/products/sandboxes/placement)を参照してください。

このガイドでは、`exec()` メソッドを使用してサンドボックスでコマンドを実行する方法を説明します。シェルコマンド、スクリプト、または対話型インタープリターをサンドボックス内で実行し、その出力を取得したり、リアルタイムでストリーミングしたり、stdin に送信したり、非ゼロの終了コードの処理方法を制御したりする場合に使用します。このガイドは、すでに `cwsandbox` Python クライアントを使用している開発者向けです。

<h2 id="run-a-basic-command">
  基本的なコマンドを実行する
</h2>

まず、完了まで実行され、取得した出力を返す単一のコマンドから始めます。`exec()` メソッドは `Process` ハンドルを返します：

```python theme={"system"}
from cwsandbox import Sandbox

with Sandbox.run() as sandbox:
    # コマンドを実行して結果を取得します
    result = sandbox.exec(["echo", "Hello, World!"]).result()

    print(result.stdout)      # "Hello, World!\n"
    print(result.returncode)  # 0
```

<h2 id="get-results">
  結果を取得
</h2>

`exec()` はすぐに返るので、コマンドの待機方法を決定できます。出力が得られるまで待機するには、`Process` ハンドルの `.result()` を呼び出します：

```python theme={"system"}
# Process をすぐに返します
process = sandbox.exec(["python", "-c", "print('hello')"])

# 結果を待機します
result = process.result()
print(result.stdout)      # "hello\n"
print(result.stderr)      # ""
print(result.returncode)  # 0

# ワンライナーのパターン
result = sandbox.exec(["ls", "-la"]).result()
```

<h2 id="stream-output">
  出力のストリーミング
</h2>

`.result()` でブロックすると、コマンドが終了するまで出力は表示されません。進捗をリアルタイムで確認するには、`.result()` を呼び出す前に `process.stdout` を反復処理します：

```python theme={"system"}
# Process を即座に返します
process = sandbox.exec(["python", "long_script.py"])

# 標準出力を1行ずつストリーミングします
for line in process.stdout:
    print(f"[stdout] {line}", end="")

# 最終結果を取得します
result = process.result()
print(f"Exit code: {result.returncode}")
```

次のことが必要な場合は、ストリーミングを使用します。

* 長時間実行されるプロセスを監視する。
* 出力を受信するたびに処理する。
* 進行状況を示すインジケーターを実装する。

<h2 id="stream-input-to-stdin">
  stdin への入力のストリーミング
</h2>

一部のコマンドは、パイプラインや対話型インタープリター、EOF まで読み込むツールなど、実行中に stdin への入力書き込みを必要とします。`stdin=True` を指定して stdin を有効にすることで、実行中のコマンドに入力を送信できます：

```python theme={"system"}
with Sandbox.run() as sandbox:
    process = sandbox.exec(["cat"], stdin=True)

    process.stdin.write(b"hello world\n").result()
    process.stdin.close().result()

    result = process.result()
    print(result.stdout)  # "hello world\n"
```

<h3 id="streamwriter-methods">
  StreamWriter のメソッド
</h3>

`stdin=True` の場合、`process.stdin` は次の 3 つのメソッドを持つ `StreamWriter` です。

* **`write(data: bytes)`**: 生のバイト列を書き込みます。`OperationRef[None]` を返します。
* **`writeline(text: str)`**: 末尾に改行を付けてテキストを書き込みます (UTF-8 にエンコードされます)。`OperationRef[None]` を返します。
* **`close()`**: EOF を通知します。システムは保留中の書き込みを先に完了します。`OperationRef[None]` を返します。

`stdin=False` (デフォルト) の場合、`process.stdin` は `None` です。

<h3 id="send-multiple-writes">
  複数回の書き込みを送信する
</h3>

閉じる前にデータを段階的に送信します：

```python theme={"system"}
process = sandbox.exec(["cat"], stdin=True)

process.stdin.writeline("line 1").result()
process.stdin.writeline("line 2").result()
process.stdin.writeline("line 3").result()
process.stdin.close().result()

result = process.result()
print(result.stdout)  # "line 1\nline 2\nline 3\n"
```

<h3 id="run-interactive-python-through-stdin">
  stdin 経由で対話型 Python を実行する
</h3>

対話型インタープリターに Python コードを入力します：

```python theme={"system"}
process = sandbox.exec(["python3"], stdin=True)

process.stdin.writeline("x = 40 + 2").result()
process.stdin.writeline("print(f'answer: {x}')").result()
process.stdin.close().result()

result = process.result()
print(result.stdout)  # "answer: 42\n"
```

<h3 id="combine-stdin-and-stdout-streaming">
  stdin と stdout のストリーミングを組み合わせる
</h3>

入力を送信しながら出力をストリーミングします：

```python theme={"system"}
process = sandbox.exec(["cat"], stdin=True)

# 入力を送信
process.stdin.writeline("hello").result()
process.stdin.writeline("world").result()
process.stdin.close().result()

# 到着した出力をストリーミング
for line in process.stdout:
    print(f"[out] {line}", end="")

result = process.result()
```

<h3 id="handle-eof-dependent-commands">
  EOF に依存するコマンドの処理
</h3>

一部のコマンド (`sort` など) は、すべての入力を読み取ってから出力を生成します。stdin を閉じて EOF を通知します：

```python theme={"system"}
process = sandbox.exec(["sort"], stdin=True)

process.stdin.writeline("banana").result()
process.stdin.writeline("apple").result()
process.stdin.writeline("cherry").result()
process.stdin.close().result()  # sort が出力を生成するには EOF が必要です

result = process.result()
print(result.stdout)  # "apple\nbanana\ncherry\n"
```

<h3 id="use-stdin-in-async-contexts">
  async コンテキストで stdin を使用する
</h3>

async コンテキストでは、各 `OperationRef` を直接 `await` します:

```python theme={"system"}
async with Sandbox.run() as sandbox:
    process = sandbox.exec(["cat"], stdin=True)

    await process.stdin.write(b"async hello\n")
    await process.stdin.close()

    result = await process
    print(result.stdout)  # "async hello\n"
```

<h3 id="when-to-use-stdintrue-compared-with-stdinfalse">
  stdin=True と stdin=False の使い分け
</h3>

| シナリオ | stdin | 理由 |
| - | - | - |
| 引数付きでコマンドを実行する | `False` | 入力は stdin ではなく引数から来る |
| パイプでデータをコマンドに渡す | `True` | コマンドは stdin から読み取る |
| 対話型インタープリター | `True` | インタープリターは stdin からコマンドを読み取る |
| EOF まで読み取るプロセス | `True` | EOF を通知するために `close()` が必要 |
| ファイア・アンド・フォーゲットのコマンド | `False` | 入力は不要 |

<h2 id="set-the-working-directory">
  作業ディレクトリを設定する
</h2>

デフォルトでは、コマンドはサンドボックスのデフォルトの作業ディレクトリから実行されます。これを `cwd` で上書きします：

```python theme={"system"}
result = sandbox.exec(
    ["ls", "-la"],
    cwd="/app/data",
).result()
```

パスは絶対パスでなければなりません。

<h2 id="set-a-timeout">
  タイムアウトを設定する
</h2>

コマンドがフリーズしたり予想以上に長く実行される可能性がある場合に停止するには、`timeout_seconds` でタイムアウトを設定します：

```python theme={"system"}
from cwsandbox import SandboxTimeoutError

try:
    result = sandbox.exec(
        ["sleep", "60"],
        timeout_seconds=5.0,
    ).result()
except SandboxTimeoutError:
    print("Command timed out")
```

<h2 id="handle-errors-with-check">
  check でエラーを処理する
</h2>

`check` パラメーターは、終了コードが 0 以外の場合のエラー処理の動作を制御します。

<h3 id="default-behavior-with-checkfalse">
  check=False のデフォルトの動作
</h3>

終了コードに関係なく結果を返します：

```python theme={"system"}
result = sandbox.exec(["false"]).result()
print(result.returncode)  # 1 (例外なし)
```

<h3 id="raise-on-failure-with-checktrue">
  失敗時に check=True で例外を送出
</h3>

非ゼロ終了時に `SandboxExecutionError` 送出される例外：

```python theme={"system"}
from cwsandbox import SandboxExecutionError

try:
    result = sandbox.exec(
        ["python", "-c", "raise ValueError('oops')"],
        check=True,
    ).result()
except SandboxExecutionError as e:
    print(f"Command failed: {e.exec_result.returncode}")
    print(f"stderr: {e.exec_result.stderr}")
```

<h2 id="run-python-code">
  Python コードを実行する
</h2>

サンドボックスは、短い ワンライナーや、インラインで渡す長いスクリプトとして Python コードを実行するためによく使用されます。

```python theme={"system"}
# 1 行のコード
result = sandbox.exec(
    ["python", "-c", "import sys; print(sys.version)"],
).result()

# 文字列からスクリプトを実行
code = '''
import json
data = {"result": 42}
print(json.dumps(data))
'''
result = sandbox.exec(["python", "-c", code]).result()
output = json.loads(result.stdout)
```

<h2 id="sequential-compared-with-parallel-execution">
  逐次実行と並列実行の比較
</h2>

後続のコマンドが先行するコマンドに依存する場合は逐次実行を選びます。コマンドが互いに独立しており、複数のサンドボックスで同時に実行したい場合は並列実行を選びます。

<h3 id="run-commands-sequentially-when-order-matters">
  順序が重要な場合のコマンドの実行
</h3>

```python theme={"system"}
# 依存関係のため逐次実行が必要です
sandbox.exec(["pip", "install", "requests"]).result()
sandbox.exec(["python", "script_using_requests.py"]).result()
```

<h3 id="run-independent-commands-in-parallel">
  独立したコマンドを並列に実行する
</h3>

```python theme={"system"}
# 複数のサンドボックスを起動します
sandboxes = [Sandbox.run() for _ in range(3)]

# 各サンドボックスでコマンドを実行します
processes = [
    sb.exec(["python", "-c", f"print({i})"])
    for i, sb in enumerate(sandboxes)
]

# すべての結果を取得します
results = [p.result() for p in processes]
for r in results:
    print(r.stdout)
```

<h3 id="wait-for-n-of-m-processes-to-complete">
  M 個のプロセスのうち N 個の完了を待機する
</h3>

`cwsandbox.wait()` を使用して、一部のプロセスの完了を待機します：

```python theme={"system"}
import cwsandbox

processes = [sb.exec(["python", "task.py"]) for sb in sandboxes]

# 最初の2つが完了するのを待つ
done, pending = cwsandbox.wait(processes, num_returns=2)

# 完了したものをすぐに処理する
for p in done:
    print(p.result().stdout)

# 残りを待つ
for p in pending:
    print(p.result().stdout)
```

<h2 id="control-processes">
  プロセスの制御
</h2>

`exec()` の呼び出しが戻った後もコマンドが実行され続ける場合、処理をブロックせずに状態を確認したり、必要に応じて完了を待ったりできます。`Process` ハンドルには、モニタリングと制御のためのメソッドが用意されています。

```python theme={"system"}
process = sandbox.exec(["python", "server.py"])

# 実行中かどうかを確認します（ノンブロッキング）
if process.poll() is None:
    print("Still running")

# 完了を待ちます
exit_code = process.wait()
print(f"Exited with code: {exit_code}")
```
