Skip to content

Strands Shell Commands

Strands Shell reimplements a curated subset of POSIX and coreutils in Rust, targeting the operations agents reach for most rather than a complete toolset. This page is the reference for what is supported and where behavior diverges from GNU or BSD: missing flags, unsupported features, and known gaps.

The shell is Bourne-compatible, with pipes, loops, functions, and subshells. The commands group into text processing, file contents, file management, path and system utilities, networking, JSON, search, and scripting.

These notes apply across commands:

  • Regex uses the Rust regex crate. Backreferences and lookaround are unavailable, so grep -P is unsupported and GNU BRE escapes are not translated.
  • jq is backed by jaq, a jq subset.
  • Unsupported flags are rejected, not ignored. Idioms such as cp -p, set -o pipefail, or ln -sf produce an error rather than silently doing the wrong thing.
  • Multiple file arguments are not uniformly supported. cut and uniq read only the first file; head and tail return a hard error; cat, sort, and wc handle multiple files correctly.
  • Malformed numeric input passes silently. test, [, and arithmetic $(( )) treat non-numeric or empty operands as 0 without an error.
  • Stdin under strands-shell -c is not connected to commands (bad fd 0). Use an in-shell pipe instead.
CommandNotable gaps
grepNo -P, backreferences, lookaround, or -f. -o on empty-matching patterns emits blank lines.
sedNo branching (b, t, :label) or multiline (N, D, P); no -f. s///N replaces the wrong match; range c emits per line.
trMissing [:punct:], [:cntrl:], and [c*n] repeats. -c two-set translate uses the wrong replacement character.
cutNo -b or --complement. Reads only the first file when given several.
sortNo -c, -o, -V, or -h (-h prints help instead). Keyed-tie order is non-deterministic. Loads all input into memory.
uniqNo -w or -D. Reads only the first file when given several.
wcNo -m (char count) or -L. Counts are correct; column padding differs from coreutils.
CommandNotable gaps
catNo -b, -s, -A, -e, or -t; no - stdin operand.
headNo -c, negative -n, or head -5 shorthand. Multiple files produce a hard error (no ==> headers).
tailNo -c, -f or -F follow, or shorthand. Multiple files produce a hard error.
teeNo -i. Standard usage (stdout plus files, -a) is supported.
CommandNotable gaps
cp-r works, including nested directories; no -p, -a, -f, or -i. cp f f silently succeeds.
mvRename, move, and cross-mount operations work; no -f, -i, -n, or -v.
rm-r, -f, and symlink non-follow behave correctly; no -d or -i.
mkdirNo -m. An invalid-option path returns exit 0.
rmdirNo -p.
touchFile creation and timestamp update only; no -t, -d, -c, or -r (cannot set a specific time).
ln-s only; hard links are refused by design; no -f, so ln -sf fails.
chmodFull support. Octal and symbolic modes; no -R.
CommandNotable gaps
ls-l omits owner, group, and link count; -a omits . and ... No -t, -S, -d, -F, or -h. Output is always single-column.
basenameNo -a or -s. basename / and "" diverge from coreutils.
dirnameSingle operand only. A trailing slash is mishandled (/usr/lib/ becomes /usr/lib).
readlinkPlain read only; no -f, -e, or -m canonicalization.
mktempNo -u or -t.
date%s is not expanded; unknown specifiers pass through literally; no -d or -r. UTC only.
envPrint-only. env VAR=v cmd, -i, and -u are unsupported; use the shell-prefix form instead.
echoExpands escapes by default; -e and -E are printed literally (escape expansion cannot be disabled).
pwdFull support, including -L and -P.
sleepNo unit suffixes (0.1s). Respects the shell timeout.
true, falseFull support.
CommandNotable gaps
curlGET, POST, JSON, headers, auth, redirects, and -w are supported. No --max-time, --connect-timeout, or --retry (risk of an indefinite hang); no -I, -F, -A, -G, or cookie jar. SSRF and credential controls are enforced.

The SSRF guard and credential injection on curl are security features, covered in the security model. They are not optional and cannot be disabled per command.

CommandNotable gaps
jq (jaq)Broad filter coverage. A missing nested key throws an error, which breaks the .a.b // default pattern; no --arg, --argjson, or -S; inputs and setpath are absent.
CommandNotable gaps
find-name, -type, -maxdepth, -exec, and -print0 are supported. No -delete, -size, -mtime, -prune, or -regex. Children are sorted alphabetically, not in readdir order.
xargsSpace-separated -n, -I, -0, and -d are supported; attached forms (-n1, -I{}) and -t, -r, -L, -P are not. Implicitly behaves as -r.
CommandNotable gaps
luaFull support. Sandboxed Lua 5.4 with VFS-backed io and os. Metatables are disabled (setmetatable removed); no os.date or debug. No wall-clock timeout under a bare -c.

Reach for lua when shell syntax gets awkward: multi-step transforms, structured data manipulation, or logic that would otherwise sprawl across a chain of pipes.

BuiltinNotable gaps
test, [No [[ ]]. Non-numeric or empty operands are treated as 0 (succeeds rather than erroring).
printfNo floating-point (%f, %e, %g print literally); %d does not parse 0x or octal prefixes.
readNo -a, -n, or -d; a prefix IFS= is ignored; -r is effectively always on.
setNo -o, so set -o pipefail fails; only e, u, and x are supported.
trapEXIT works; numeric signals (trap ... 0) are ignored; -p and -l are no-ops.
aliasCan be defined and listed, but aliases are never expanded during execution.
readonlyEnforced, but a violation returns exit 0; no -p.
localWorks within functions; silently succeeds when used outside a function.
typeNo -t or -a.
cdNo CDPATH; -P and -L are not parsed.
getopts, export, unset, shift, umask, hash, wait, :Full support.

Arithmetic $(( )) handles precedence, bitwise operators, the ternary, hex, and octal correctly. Malformed input returns a wrong result with exit 0 ($((2 3)) yields 2, $((1/0)) yields 0). Post-increment x++ and x-- return the value without updating the variable.

FeatureSupported
Pipelines and lists|, &&, ||, ;
Redirections>, >>, <, 2>, &>, here-docs <<
Conditionalsif, elif, else, case
Loopsfor, while, until
Functionsdefinitions, local variables, return
Groupingcommand groups { }, subshells ( )
Expansionvariables (${VAR:-default}, ${VAR%pat}, ${#VAR}), command substitution (`cmd`, $(cmd)), arithmetic $(( )), globs
Quotingsingle, double
Jobsbackground &
Scripts. script.sh, source