How to Syntax Check a Bash Script Without Running It

How do I syntax check a Bash script without running it?

bash -n scriptname

Perhaps an obvious caveat: this validates syntax but won't check if your bash script tries to execute a command that isn't in your path, like ech hello instead of echo hello.

How to syntax check a shell script before sourcing it?

You could use bash -n (zsh has has a -n option as well) to syntax check your script before sourcing it:

 env_auto_sourcing() {
if [[ -f .env ]]; then
if errs=$(bash -n .env 2>&1);
then source .env;
else
printf '%s\n' "Hey you got errors" "$errs";
fi
fi
}

Storing the syntax check errors in a file is a little cleaner than the subshell approach you have used in your code.

bash -n has a few pitfalls as seen here:

  • How do I check syntax in bash without running the script?

How to check for bash shell syntax errors in practice?

bash -n checks whether Bash can parse the code (that is, the syntax is correct), not whether the code is "correct." "Correct" can have a lot of meanings, most of which programs will never be able to verify:

  • Can be parsed (bash -n).
  • Finishes without error (if ./script.sh; then [...]; fi).
  • Prints something which follows a specific format.
  • Prints something useful.
  • Any of the above within a specific environment, for example one which has a shell interpreter that lives in /bin1/bash1 and a command eco which shows you the most ecologically friendly beer bottles available within a 5 parsec radius.

How to syntax check portable POSIX shell scripts?

All POSIX-compatible Shell Command Language shells support the set -n built-in which can be used to check the syntax of the script. Therefore it is possible to prepend

set -n

to your code to syntax check it. Note also that standard sh utility is also required to support a command-line -n flag, which has equivalent semantics to using set -n. Bash and possibly other shells also support this command-line flag. Therefore you can simply run the following to syntax check your script:

sh -n yourScriptFilename.sh

WARNING: This does not give you a guarantee that the script has fully POSIX compatible syntax. For example, Bash allows bashisms (e.g. arrays and c{a,u}t) to go unnoticed even when using the --posix (and/or +B) command line option in addition to -n when invoked as sh. Other shells might have similar issues.

Show commands without executing them

This thread would tell you why the option to show commands instead of executing those (a.k.a dry run) would never be implemented for bash.

Refer to the response from Eric Blake:

> My question is why can't such an option or be provided,

A little thought would show why this will never be implemented. What
would such an option output for the following:

if complex_command; then
foo=command1
else
foo=command2
fi
$foo args

On the line for $foo args, there is no way to know what $foo expands
to unless you have previously executed (not just scanned) the
complex_command. Therefore, there is no way to dry run what the final
results will be without running things, but running things is counter
to the goal of a dry run.

That said, you might be interested in the bashdb project, which uses
bash hooks to provide a debugger interface where you can single-step
through a bash script; it's not the same as telling you what the
script would do, but it at least lets you control how much or little
of the script is actually run.



Related Topics



Leave a reply



Submit