Skip to content
shellhacks.dev
Testing

Run ShellCheck on Every Script in a Project with xargs

Run ShellCheck on every script by feeding find -print0 to xargs -0, then catch files without a .sh suffix by searching for a shell shebang. xargs exits 123 on findings.

2 min read
Summarize in AI

A repository holds many shell scripts and some have no extension, so a single glob misses them.

Shell
mkdir -p src/lib
printf '#!/bin/bash\necho $1\n' > src/bad.sh
printf '#!/bin/bash\necho "$1"\n' > src/lib/good.sh
printf '#!/bin/bash\nfor f in $(ls); do echo "$f"; done\n' > src/deploy
find . -name '*.sh' -print0 | xargs -0 shellcheck -f gcc
echo "exit status: $?"
echo "--- everything with a shell shebang"
find . -type f -print0 | xargs -0 grep -lZ '^#!.*sh' | xargs -0 shellcheck -f gcc
echo "exit status: $?"
Text
./src/bad.sh:2:6: note: Double quote to prevent globbing and word splitting. [SC2086]
exit status: 123
--- everything with a shell shebang
./src/bad.sh:2:6: note: Double quote to prevent globbing and word splitting. [SC2086]
./src/deploy:2:10: error: Iterating over ls output is fragile. Use globs. [SC2045]
exit status: 123

find . -name '*.sh' -print0 | xargs -0 shellcheck passes every matching path safely, and -f gcc prints one line per finding. It found SC2086, a missing quote, in bad.sh and missed src/deploy, which has no suffix. The second pipeline searches all files for a shell shebang with grep -lZ and also found SC2045, iterating over ls. xargs exits with 123 when any run of ShellCheck returned a failure, which is a signal for CI. See SC2086.

A shebang search reads every file, including binaries, so limit it to tracked files with git ls-files -z in a large repository. Scripts for another shell need the -s option or a shell= directive. This run used ShellCheck 0.9.0.

Share

More snippets

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.