Reference

Shell Behavior

The host shell model ota uses for task and service execution.

referenceautomation buildersintermediatestable2026-05-30

When to use this page

Use this page when you need to know exactly how ota runs commands on the host.

Shell behavior matters because the same contract can behave differently on Linux, macOS, and Windows.

  • task bodies must match the target platform shell
  • service commands and checks use the same invocation model as tasks
  • ota does not translate shell syntax for you
  • if a command works only in one shell, encode that difference in the contract

Host shell model

  • Unix-like systems use sh -lc
  • Windows uses cmd /C
  • task run and script use the same platform shell model
  • service start, stop, and healthcheck commands use the same model
  • configured checks use the same model

Working directory

  • if you pass a direct ota.yaml path, ota runs commands from that file’s parent directory
  • if you pass a directory, ota runs commands from that directory
  • if you pass no path, ota discovers the contract upward from the current directory
  • the working directory is the contract boundary, not the shell current directory by accident

Environment behavior

  • configured env values are applied to task execution
  • required env values must be present or resolvable from defaults where allowed
  • ota does not translate shell syntax across platforms
  • env values are injected before the shell runs, so shell bodies can rely on them directly

run vs script

  • run is a single command string
  • script is a multiline shell body
  • both execute through the same platform shell model
  • use run for one command you would type directly
  • use script when the task needs setup, cleanup, or multiple shell statements

Real example

This example shows how to keep one task portable while still respecting platform-specific shell syntax.

ota.yamlyaml
tasks:  test:    variants:      - when:          os: linux        script: |          set -euo pipefail          export NODE_ENV=test          mkdir -p .tmp/test-logs          pnpm install --frozen-lockfile          pnpm lint          pnpm test -- --runInBand          pnpm exec playwright test --project=chromium      - when:          os: macos        script: |          set -e          pnpm test -- --runInBand          pnpm exec playwright test      - when:          os: windows        command:          exe: pnpm          args:            - test

What users should expect

  • write task and service commands with their supported platforms in mind
  • use task variants when Windows needs different shell syntax
  • ota guarantees the invocation model, not shell portability
  • if you need Bash-only behavior, make that explicit in the command body and in the platform choice

Use cases

  • a repo works on Linux and macOS, but Windows needs different shell syntax
  • a task needs a multiline setup script instead of one shell string
  • a service healthcheck depends on a command that only exists in the repo shell environment
  • a CI job needs to know whether ota will call sh -lc or cmd /C
  • an agent needs to know whether a task body is safe to run on the current platform

What ota does not do

  • no per-task shell selection
  • no PowerShell-specific execution mode in V1
  • no Bash-only contract mode
  • no shell portability translation
  • no isolated shell environment for ephemeral
  • no hidden shell fallback when a command fails because the wrong syntax was used