Scripting & Automation

contree-cli is designed for scripting. Exit codes propagate, output formats are machine-readable, and shebang mode lets you write executable sandbox scripts.

Shebang scripts

Note

Shebang scripts are a CLI-only feature. They are not available in the interactive shell.

Any file with a contree run -I shebang runs inside a sandbox:

#!/usr/bin/env -S contree run -I
echo "Hello from a ConTree sandbox"
uname -a

Save it, chmod +x, and run it directly:

chmod +x hello.sh
./hello.sh

The -I (interpreter) flag reads the script, strips the shebang line, and sends the body as stdin to /bin/sh -s inside the sandbox.

Combining flags

Shebang flags stack. A disposable run with a 10-second timeout:

#!/usr/bin/env -S contree run -I -D -t 10
apt-get update -qq
apt-get install -y curl
curl https://example.com

Since -D is set, the session image is not advanced – the script runs in a throwaway sandbox.

Passing arguments

Extra arguments after the script name are forwarded to the shell:

#!/usr/bin/env -S contree run -I
echo "arg1=$1 arg2=$2"
./script.sh foo bar
# arg1=foo arg2=bar

Note

The -S flag on /usr/bin/env is required because the contree entry point is a Python script. Without -S, the kernel sees a nested shebang (script -> script -> binary) and returns ENOEXEC. Using /usr/bin/env -S (a real binary) splits the argument string and avoids this.

Execution modes

Direct command

The default mode. Each positional argument becomes a separate argv entry:

contree run uname -a
uname -a

Shell mode

-s joins all arguments into a single shell expression:

contree run -s -- 'echo hello && ls /'
echo hello && ls /

Bare commands in the shell always use shell mode.

Useful when you need pipes, redirects, or && chains.

Piped stdin

Note

Piped stdin is a CLI-only feature. It is not available in the interactive shell.

When stdin is not a TTY, it is read, base64-encoded, and sent to the sandbox:

echo 'uname -a' | contree run /bin/sh
cat deploy.sh | contree run /bin/sh

Detached mode

-d spawns the operation and exits immediately, printing the operation UUID:

contree run -d -- long-running-task

Check on it later:

contree show UUID
contree run -d -- long-running-task
contree show UUID

Flags like -d require the explicit contree run prefix.

Exit codes

Note

Exit code propagation is a CLI-only feature useful for scripting. The interactive shell does not expose sandbox exit codes.

The sandbox exit code propagates to the CLI process:

contree run -- /bin/sh -c 'exit 42'
echo $?    # 42

This means contree run works naturally in if, &&, ||, and set -e scripts:

set -e
contree run -- make test          # script aborts if tests fail
contree run -- make install

If the operation fails at the platform level (timeout, cancelled), the CLI exits with code 1.

Environment variables

Pass environment variables into the sandbox with -e:

contree run -e DEBUG=1 -e DB_HOST=postgres -- ./app
contree run -e DEBUG=1 -e DB_HOST=postgres -- ./app

Flags like -e require the explicit contree run prefix.

The flag is repeatable. Format is KEY=VALUE.

Output truncation

By default, stdout/stderr is capped at 64 KiB in the API response. Override with -T:

contree run -T 1048576 -- ./generate-big-output.sh
contree run -T 1048576 -- ./generate-big-output.sh

Monitor operations

List running and recent operations:

contree ps            # active operations only
contree ps -a         # all (including completed)
contree ps -q         # UUIDs only, one per line
contree ps
contree ps -a
contree ps -q

Show the full result of a specific operation:

contree show UUID
contree show UUID

Cancel an operation:

contree kill UUID
contree kill --all
contree kill UUID
contree kill --all

Scripting patterns

Note

Shell piping and command substitution are CLI-only features. These patterns are not available in the interactive shell.

Combine -q with other tools:

# Show results of all active operations
contree ps -q | xargs -I {} contree show {}

# Kill all running operations
contree ps -q | xargs -I {} contree kill {}

# Launch detached, capture UUID
OP=$(contree run -d -- sleep 3600)
# ... do other work ...
contree show "$OP"

Output formats

Note

The --format flag is global and set at CLI launch time. In the interactive shell, the format is fixed for the entire session and cannot be changed mid-session.

Use -f / --format to control output. The flag is global and goes before the subcommand:

default : Table-like output optimized for human reading. Some commands (like run) use a custom default that prints only stdout/stderr.

table : Aligned columns with headers. Identical to default for most commands.

csv : Comma-separated values with a header row. Useful for spreadsheet import or cut/awk processing.

tsv : Tab-separated values with a header row. Works well with column -t.

json : One JSON object per line (JSONL/NDJSON). Each output row is a separate JSON object. Suitable for jq processing.

json-pretty : All rows collected into a single pretty-printed JSON array. Output is flushed at the end.

Examples

# Pipe JSON to jq
contree -f json ps | jq '.uuid'

# CSV for scripting
contree -f csv images --tagged > images.csv

# Tab-separated for column alignment
contree -f tsv ps | column -t

# Get image UUID from tag
contree -f json images --prefix=ubuntu | jq -r '.uuid'

Streaming behavior

json and json-pretty formatters support streaming output from commands like run and show – stdout/stderr are included in the JSON payload.

csv, tsv, and table formatters do not include stdout/stderr from sandbox execution. Use default or json formats to see sandbox output.

Session management in scripts

Note

Script-level session management with eval and CONTREE_SESSION is a CLI-only pattern. The interactive shell manages sessions automatically.

The eval $(contree use ...) pattern exports the session key into your shell. In scripts, set CONTREE_SESSION explicitly to control which session you operate on:

#!/bin/bash
export CONTREE_SESSION=ci-build-$$
contree use tag:ubuntu:latest
contree run apt-get update -qq
contree run apt-get install -y build-essential
contree run --file ./src:/src make -C /src test

Using $$ (PID) or a fixed name gives you a predictable, isolated session per script run.


You now know the full CLI. Next: Configuration & Profiles.