jq @sh : Shell-Quote Values Safely
jq @sh escapes a string or array so it can be safely interpolated into a shell command.
When a workflow builds a command from API data, @sh quotes each argument so spaces and special characters cannot break out into the shell.
What it does
@sh wraps a string in single quotes and escapes embedded single quotes, producing a shell-safe token. Applied to an array it emits each element as a separate quoted word, ideal for building an argument list to eval.
Common usage
# build safe positional args
jq -r '@sh "deploy \(.name) \(.env)"' job.json
# turn an array into eval-safe words
echo '["a b","c;d"]' | jq -r '@sh'
# assign shell vars from JSON
eval "$(jq -r '@sh "NAME=\(.name) SHA=\(.sha)"' build.json)"Formats
| Form | What it does |
|---|---|
| @sh on a string | Single-quoted, escaped token |
| @sh on an array | Each element as a quoted word |
| -r | Emit the quoted text raw |
| eval "$(... @sh ...)" | Safely assign shell variables |
In CI
@sh is the safe way to move JSON values into shell variables; it neutralizes spaces, quotes, and semicolons that would otherwise let API content inject commands. Always combine with -r and eval the result.
Common errors in CI
"jq: error (at <stdin>:0): Rendering object as shell-quoted string is not allowed" means you passed an object to @sh; reduce it to scalars or an array of scalars first. A null value renders as the literal null token, which can surprise an eval; default it with (.x // "").