exec.md

Executing Commands

devbox exec runs a command inside a Devbox without opening an interactive shell. Each run is recorded as an execution with its own ID, and its output is retained on the Devbox — so you can stream it live, or come back and read it later with devbox logs.

This makes devbox exec a good fit for scripted and automated work: builds, test suites, migrations, and anything driven by a coding agent.

Running Commands

Run a command and stream its output back to your terminal.

CLI

devbox exec my-devbox ls

When the command has flags of its own, add -- to separate the Devbox CLI arguments from the command that should run inside the Devbox:

devbox exec my-devbox -- ./scripts/test.sh

TS SDK

devbox.exec() takes the executable and its arguments, and resolves with the output and exit code:

const result = await devbox.exec(["./scripts/test.sh"], {
  onStdout: (data) => process.stdout.write(data),
  onStderr: (data) => process.stderr.write(data),
});

process.exitCode = result.exitCode ?? 1;

A non-zero exit code resolves normally rather than throwing, so check exitCode yourself. Use devbox.shell() when the command needs pipes, redirects, or variable expansion. See Run commands.

Detached Executions

Coding agents often need to start a long build or test run without blocking on it. devbox exec -d starts the command and returns immediately, leaving it running on the Devbox. It prints an execution ID, which the agent uses to check the output when it needs the result:

devbox exec -d my-devbox -- ./scripts/long-build.sh
exec_nl1f65debpkamdbdnuqra114cc

A detached execution keeps running after the CLI exits. A foreground execution, by contrast, is tied to your CLI session, so prefer -d for long-running work or when your connection might drop. However, a detached execution ends if the Devbox stops. For a process that should keep running, restart when it fails, and start again on boot, create a service instead.

Streaming Logs

Output from every execution is retained on the Devbox, so you can read it while a command is still running or long after it has finished. Retained output survives pause and resume, and is removed when the Devbox is deleted.

Stream the output of an execution by ID:

devbox logs my-devbox exec_nl1f65debpkamdbdnuqra114cc

devbox logs first replays the output that has already been captured, then follows the live output, and returns once the execution completes. This works for executions that have already finished too, which is how you re-read the results of an earlier run.

Listing Executions

List the executions retained on a Devbox:

Table

devbox logs list my-devbox
 ID                               Command             Started          Status
 exec_ftv7gbs955agrel08t5u6tv67c  ./scripts/lint.sh   Jul 29 16:05:11  completed
 exec_bf1p8g8uimrcjrvclteb5t5d48  ./scripts/test.sh   Jul 29 16:07:42  failed (1)
 exec_nl1f65debpkamdbdnuqra114cc  ./scripts/build.sh  Jul 29 16:08:10  running

The Status column is running while the command is still going, then completed, or failed with the command's exit code.

JSON

devbox logs list my-devbox -o json
{
  "actions": [
    {
      "id": "exec_bf1p8g8uimrcjrvclteb5t5d48",
      "command": {
        "command": "./scripts/test.sh"
      },
      "started_at": "2026-07-29T14:07:42.594451722Z",
      "completed_at": "2026-07-29T14:07:49.262962529Z",
      "error": "./scripts/test.sh failed: exit status 1",
      "exit_code": 1
    }
  ]
}

error and exit_code are only present when the execution failed, and completed_at is unset while it is still running. Executions are listed in the order they started.

Next Steps

Open a shell on a Devbox with SSH or a session.

Keep a Devbox running while a build or an agent works.

Drive Devboxes from AI coding agents.