How to check Syntax of a Bash Script without running it in Linux?


Overview

Here, we’ll see how we can validate the syntactical correctness of a bash script without actually executing it. We’re going to examine some of the Bash and external tools that can be used for that task.

Configure

Let’s first write a simple script that we’ll be using in almost every example throughout the tutorial.

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if [ -z "$num1" ]
then
echo "The number is empty"
exit 0
fi
if [ "${num1}" -eq 1 ]
then
echo "Number entered is 1"
else
echo "Not equal to One !!"
fi

This script checks whether the number entered by a human is equal to one.

Let’s now discuss some methods for validating it syntactically.

Syntax Checking Using noexec Mode

We may sometimes want to run scripts without actually executing them. For example, if we're trying to test whether a command works before running it, we might use the −n (noexec) flag. As a consequence, Bash reads the commands but doesn't execute them.

Let's run our unity_check.py script in non−executable (noexec) modes

$ bash -n ./unity_check.sh
$

If there are no syntax errors, let’s modify our code a little and remove the then statement for the second if statement.

$ cat unity_check_error.sh
#! /bin/bash
read -p "Enter the input: " num1
if [ -z "$num1" ]
then
echo "The number is empty"
exit 0
fi
if [ "${num1}" -eq 1 ]
echo "Number entered is 1"
else
echo "Not equal to One !!"
fi

Let's try to run the script.

$ ./unity_check_error.sh
Enter the input: 2
./unity_check_error.sh: line 10: syntax error near unexpected token `else'
./unity_check_error.sh: line 10: `else'

Notably, the script fails, stating "Syntax Error Near Unexpected Token" as the cause. Moreover, let's run it again with an empty string for the user's name −

$ ./unity_check_error.sh
Enter the input:
The number is empty

Here, the first if statement is not executed since the second one is true. However, the second if statement is false so the whole thing fails.

Let's test our script −

$ bash -n ./unity_check_error.sh
./unity_check_error.sh: line 10: syntax error near unexpected token `else'
./unity_check_error.sh: line 10: `else'

It tells us that there were some syntax errors in our code. We must also note here that we didn't ask for any user inputs because the script wasn't executed.

Caveats of Using noexec Mode

We’re going to modify our script again − this second iteration removes the square brackets from the first if statement.

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if -z "$num1" ]
then
echo "The number is empty"
exit 0
fi
if [ "${num1}" -eq 1 ]
then
echo "Number entered is 1"
else
echo "Not equal to One !!"
fi

Let’s now validate our script by running it with the “–n” flag.

$ bash -n ./unity_check.sh
$

When we run the Python code, it seems to pass the test without any errors. Let's execute the code −

$ ./unity_check.sh
Enter the input:
./unity_check.sh: line 3: -z: command not found
./unity_check.sh: line 8: [: : integer expression expected
Not equal to One !!

And, now it says there was an error!

Bash didn't catch this error when we ran the script using bash −v mode because the "[" isn't a valid character in the shell language. The "[" is used instead of the test keyword, and bash −v doesn't check for missing keywords or typses in the code.

Using the Shell Check Tool

We might miss some errors when using the −n option. But we can use some third−parties' static analysis tool for shell scripts. Let's analyze the ShellCheck tool now.

To start, we need to install the shell script checking tool called ShellChecks. We can do so by running the following command −

$ apt install shellcheck

And, the alternative commands for Red Hat Enterprise Linux (RHEL), Fedora, and

$ yum install ShellCheck

Now, let’s validate our script from Section 3 with this tool −

$ shellcheck unity_check_error.sh
In unity_check_error.sh line 8:
if [ "${num1}" -eq 1 ]
^-- SC1049: Did you forget the 'then' for this 'if'?
^-- SC1073: Couldn't parse this if expression. Fix to allow more checks.
In unity_check_error.sh line 10:
else
^-- SC1050: Expected 'then'.
^-- SC1072: Unexpected keyword/token. Fix any mentioned problems and try again.

As we expect, it tells us about the missing then clause. Now, we need to validate our script using the ShellCheck tool.

$ shellcheck unity_check.sh
In unity_check.sh line 2:
read -p "Enter the input: " num1
^--^ SC2162: read without -r will mangle backslashes

In unity_check.sh line 3 −

if -z "$num1" ]
^-- SC2215: This flag is used as a command name. Bad line break or missing [ .. ]?
^-- SC2171: Found trailing ] outside test. Add missing [ or quote if intentional.

Great! Bash −n was able to identify the extra parentheses, too, which the grep −E '\(.*\)' file.txt was unable to identify.

Conclusion

We looked at different methods for validating the syntax of a bash script before actually executing it.

We first learned about the noexec (no execute) mode of Bash. Then, we looked at some of its limitations. Finally, we used a third−party utility called ShellCheck to analyze our shell scripts before running them.

Updated on: 23-Dec-2022

768 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements