Shell and script actions
Run shell commands and module scripts with checks, output, timeouts and privilege options.
Use shell for small inline commands and script for executable assets owned by a
module. Use a check when a successful repeat should skip execution.
{"shell": [{
"description": "Prepare application state",
"command": ["example", "init"],
"check": {"directory_exists": "~/.example"},
}]}
{"script": {"path": "scripts/setup.sh", "args": ["--yes"]}}Shell accepts one option dictionary or an ordered list. On Linux/macOS a command string executes
through /bin/sh -c; a command argument list bypasses shell parsing. Windows uses
its supported PowerShell behavior; see Windows commands. Script accepts
one dictionary with a module-relative path and optional args list. Its file must
be executable and remain within the module root; interpreters come from its shebang.
Large local workflows belong in script files rather than long command strings.
Shared options and context
Both providers support description, quiet, stdin, sudo, env, check and timeout.
These options may be provider defaults with entry-level replacement semantics.
Timeout defaults to 300 positive finite seconds. quiet/stdin/sudo default to False.
Successful command output is captured by default in a temporary disk file.
Failures and timeouts include the last 16 KiB of combined stdout/stderr in the
error; temporary output is removed afterward. etch apply --verbose streams
child output instead. quiet: True suppresses streaming even in verbose mode,
but retains captured failure diagnostics. stdin: True and sudo: True keep
live input/output so interactive prompts remain visible. Verbose parallel child
output may interleave; default captured failure output stays attached to its
action. Third-party plugins control their own output; bundled Homebrew and VS
Code providers already capture their tool output for inspection and errors.
Without stdin True, commands read from the null device.
Execution uses the module root as cwd and inherits the user environment, followed by explicit env overrides. Etch then sets ETCH_MODULE_DIR, ETCH_REPO_DIR, ETCH_MODULE, ETCH_OS, ETCH_DISTRO and ETCH_ARCH. These metadata names cannot be overridden by env. Unavailable platform metadata is an empty string. env replaces individual inherited variables; it does not clear the environment.
Checks support one of command, path_exists, file_exists or directory_exists.
Filesystem checks expand ~ and anchor relative paths to the module root. Command
checks use PATH from the action environment. Passing checks skip commands and are
rechecked before application; no arbitrary shell/Python check language is provided.
Honest plans and privilege
An unsatisfied action plans RUN with opaque side effects; arbitrary commands are not treated as reconciled declarative state. Without a check, reruns execute again. Known input requirements produce stdin-interactive and sudo-interactive resource metadata. Opaque commands may use network resources the provider cannot infer.
sudo: True requests elevation but does not authorize it. Application
also requires etch apply --allow-sudo. Etch prefixes sudo -E --
to that command only. Sudo policy controls environment preservation and may reject
the request; errors propagate. Etch never elevates the whole process or defaults to
privilege. Interactive input and elevation remain serialized even with multiple jobs.
Windows does not support sudo actions.
Failures and scope
Application checks runnable scripts and elevation requirements, then processes entries in order. A nonzero exit or timeout raises an error and stops later entries. Earlier side effects are not rolled back. Checks can allow a second run to skip; the returned changed flag means a command ran, not that Etch understood its effects. Rebuild plans after relevant state changes, as with other providers.
Only the launched process is covered by subprocess timeout handling; this is not process-tree orchestration. Scripts and commands are trusted executable content. See applying and scheduling for failure and parallelism behavior.
Plan and apply print a flushed startup line and one Checking <module>... line
before module inspection, including potentially slow facts/provider probes.
Apply also reports Applying <module>... before changing that module. Repeated
staged planning does not repeat inspection progress lines. These messages are
plain lines in terminals and CI, with no spinner or extra dependencies. A long
single probe can still take time after its module line appears.