5

The following shell script executes well when provided /bin/true for the first argument, but may otherwise fail with a syntax error during execution!

#!/bin/sh
if $1 ; then exit; fi
/tmp/asdf <<< ASDF # Something with syntax error in POSIX

Surely some syntax errors (if not all?) can be avoided by static checking? How do I statically check whether a given Shell Command Language script is syntactically valid?

EDIT: Checking for syntax errors in Bash scripts has been answered in this question.

EDIT #2: Note that Bash fails to properly check whether the syntax adheres to POSIX even when executed with the +B and --posix flags in addition to -n.

6
  • 4
    shellcheck.net is a useful resource and as I recall you can download a standalone tool. Commented Apr 27, 2016 at 10:39
  • 1
    @tripleee Please reconsider whether this really is a duplicate. Commented Apr 27, 2016 at 12:41
  • The duplicate asks for a Bash solution but the answers are fine for POSIX, too. The duplicate link could go the other way if the shellcheck.net answer is migrated here, but I don't really see the need -- this duplicate works as a signpost for people searching for a POSIX solution. Commented Apr 27, 2016 at 16:35
  • 1
    @tripleee Actually this question appears to be more of a duplicate of this question (which is also a duplicate of this one on Unix&Linux). Commented Apr 27, 2016 at 16:49
  • @jotik Nominally a better question, but its sole answer is rather unsatisfactory. Commented Apr 27, 2016 at 17:24

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Upvote for for POSIX link.
Why do you ask a question and then duplicate what I said in your own answer? Furthermore it is not useful to change a file, add set -n on top before you syntax check it and remove that afterwards. Using -n as the command line option, as I told, makes much more sense.
@hek2mgl Sportsmanship. :-) Note that I didn't accept my own answer, because it doesn't fully answer my question. I urgently need to test a large number of shell scripts for POSIX compatibility (syntax only or as far as possible), which is why I need a reliable means to do it.
Use bash --posix -n for that. If you have a more posix compatible shell at the hand, check if it is supports the -n option as well. dash for example supports the -n option.
The Debian devscripts (deb package, git) contain checkbashisms to "check whether a /bin/sh script contains any common bash-specific constructs" (see also this answer).
5

With bash you can use -n:

bash -n file.sh

Output:

a.sh: line 3: syntax error near unexpected token `then'
a.sh: line 3: `if then fi # Something with syntax error'

Since bash supports the --posix options you may run

bash --posix -n file.sh

to perform a posix compatible check. I don't know how posixly correct that mode is in detail.

5 Comments

I assume this only checks for Bash syntax, but not POSIX?
Yes, that checks only for bash syntax. However other shells (might) have similar options. dash for example supports -n as well. Which POSIX shell do you have in mind?
I think the correct term is "Shell Command Language".
You can run bash --posix -n
I just amended my answer with a warning about Bash not fully respecting bash --posix -n.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.