Skip to content

bhatti exec

Execute a command inside a sandbox. The exit code of the child process is forwarded to the CLI’s exit code. Sleeping sandboxes wake automatically.

bhatti exec <sandbox> [--] <command...> [flags]

The -- separator is optional — bhatti exec dev echo hello works just like bhatti exec dev -- echo hello. Use -- only when the command contains flags that cobra would otherwise try to parse (e.g. bhatti exec dev -- ls -la /tmp).

Commands run as the unprivileged user lohar (uid 1000), not root. Use sudo inside the sandbox for root operations. Stdout and stderr are kept on separate streams; when output is captured, the result distinguishes them.

Output mode auto-detects:

  • Stdout is a TTY → streaming NDJSON, line-by-line, flushed as the process emits it. You see npm install’s progress bar in real time.
  • Stdout is a pipe or --json is set → buffered. The CLI prints a JSON object {exit_code, stdout, stderr} once the command finishes.
  • BHATTI_FORCE_STREAM=1 → forces streaming even when piping. Useful for CI logs that want progressive output.

Cold sandboxes wake transparently. If the sandbox is cold or warm, the server resumes it before executing — typically ~50ms for cold, sub-millisecond for warm. The wake is invisible to the caller; the command just takes a bit longer.

Failures get recovery hints. Common errors (sandbox not found, sandbox not running, name conflict, quota reached) are followed by a one-line suggestion in stderr. For example:

404 Not Found: sandbox not found
Check sandbox name:
bhatti ls
Terminal window
# Most basic
bhatti exec dev -- echo hello
Terminal window
# -- is optional
bhatti exec dev echo hello
Terminal window
# Pipe output to other tools — CLI switches to buffered mode automatically
bhatti exec dev -- cat /workspace/data.json | jq .name
Terminal window
# Shell expansion needs a shell — env vars in the *guest*, not in your terminal
bhatti exec dev -- bash -c 'echo $API_KEY'
Terminal window
# Cap a long-running command at 60s
bhatti exec dev --timeout 60 -- ./benchmark.sh
Terminal window
# Run in the background, return immediately with the guest PID
bhatti exec dev --detach -- ./worker.sh
pid: 4218
output: /var/log/lohar/sessions/sess-7b3c.log
FlagDefaultDescription
--timeout <int>300Exec timeout in seconds. The server kills the process group on timeout and returns exit code 137. Hard max: 86400 (24 hours).
--detachfalseRun the command in the background and return immediately with the guest PID and the path to the captured output file. The session continues until it finishes or is killed.

See Global flags for --url, --token, --json, --timing, --data-dir.

CodeMeaning
<n>The child process’s exit code is forwarded verbatim.
137The child was killed (timeout exceeded, or session manually killed).
1CLI / API error before the command ran (sandbox not found, network, auth).