Ad-hoc Commands (orchstep do)
Run any shell command or script with your OrchStep vars and environment, without writing a task — inline, piped, as a script, or in an interactive REPL.
Ad-hoc Commands — orchstep do
Pointed at a folder of environment files,
orchstep dois also known as OrchShell — dotenv++ for applications.
Sometimes you don't want to write a task — you just want to run one command, but
with your project's variables and environment already filled in. That's
orchstep do:
orchstep do 'echo "Building v{{ vars.version }} for {{ vars.env }}"' --env prod
# Building v1.2.3 for productionIt renders {{ vars.X }} / {{ env.X }} against the same context a run would
have — your orchstep.yml defaults, environment groups/environments
(--env), dotenv, and --var/--vars-file — then executes the result. Output
is bare passthrough and the command's exit code is propagated, so it drops cleanly
into scripts and pipelines.
Think of it as the ad-hoc counterpart to orchstep run — like
ansible -m shell -a next to ansible-playbook. (And it's the execute sibling
of orchstep eval, which only renders a value.)
Four ways to give it a command
1. Inline argument
orchstep do 'kubectl set image deploy/app app={{ vars.image }}'Quote the whole command so the shell hands it to OrchStep intact.
2. Stdin / pipe — run a whole script
cat deploy.sh | orchstep do --env prodAnything you pipe in is rendered, then run. Great for one-off scripts you don't want to commit as tasks.
3. A script file (with arguments)
orchstep do --script ./deploy prod canary
# ^path ^$1 ^$2Remaining arguments become the script's positional parameters ($1, $2, …).
4. Shebang — make any script context-aware
Put OrchStep on the shebang line and the whole script becomes a context-aware program:
#!/usr/bin/env -S orchstep do --script
echo "Deploying v{{ vars.version }}"
kubectl set image deploy/app app={{ vars.image }}chmod +x deploy && ./deployThe #! line is a shell comment, so it's ignored when the script runs. This turns
executable runbooks into things that pull straight from your env config.
Preview without running: --render
See exactly what a command will expand to — a context-aware envsubst:
orchstep do --render --env prod 'flyctl deploy --image {{ vars.image }}'
# flyctl deploy --image registry/app:1.2.3Switch environments
The same command against different environments is just --env:
orchstep do --env staging 'echo {{ vars.db_host }}'
orchstep do --env prod 'echo {{ vars.db_host }}'Interactive REPL
Run orchstep do with no command in a terminal to drop into an interactive shell
where your vars are already loaded:
$ orchstep do --env prod
orchstep do — interactive shell (vars/env from your OrchStep context). Ctrl-D to exit.
orchstep> echo deploying {{ vars.version }}
deploying 1.2.3
orchstep> cd services/api
orchstep> for s in web api; do echo "restart $s"; done
restart web
restart api
orchstep>The REPL is stateful — cd, export, and multi-line constructs persist
across lines, exactly like consecutive lines of a single step's do: block. Your
OrchStep vars stay constant for the session; the shell's own state (current
directory, exports) carries over. Multi-line commands (for, if, heredocs) show
a ...> continuation prompt until they're complete, just like bash.
The REPL uses OrchStep's built-in POSIX shell for its stateful session; one-shot modes use your configured shell (bash by default). POSIX-compatible commands behave the same either way.
No orchstep.yml? Still works
With no workflow file in the directory, orchstep do runs with your OS
environment plus any --var you pass:
orchstep do --var name=World 'echo "hello {{ vars.name }} from $USER"'
# hello World from youIt also picks up ambient context from convention-based files in the directory:
an environments/ directory (per-environment application vars, used with --env)
and the dotenv: declared in an orchstep_config.yml. See
OrchShell for that pattern. (A bare .env is not
auto-loaded — dotenv must be declared, so an untrusted directory can't slip env
vars into your commands.)
Use cases
One-off deploy against an environment
orchstep do --env prod 'helm upgrade app ./chart --set image.tag={{ vars.version }}'Context-aware runbooks (shebang) — commit an executable script that reads from
your env config; teammates run ./rotate-certs and it picks up the right hosts.
CI ad-hoc steps — render a command with the pipeline's vars without adding a task:
orchstep do -f ci.orchstep.yml 'docker push {{ vars.registry }}/app:{{ vars.version }}'Interactive prod inspection — orchstep do --env prod gives you a shell where
{{ vars.db_host }}, {{ vars.namespace }}, etc. are already correct.
Scripting & exit codes
orchstep do propagates the command's real exit code, so it composes:
orchstep do --env prod 'health-check {{ vars.url }}' || rollbackBest practices
- Quote the command (
'…') so your shell passes it to OrchStep unsplit. - Use
--renderfirst when a command is destructive — confirm the expansion. - For anything you run repeatedly or want reviewed, promote it to a task in
orchstep.yml;dois for the ad-hoc and exploratory. - Secrets resolve into the environment (referenced as
$X), not rendered into the command text — same model as a normal step.
See also
orchstep run— the structured, reusable counterpart.- Environments and Environment Variables — where the context comes from.