Keywords: Bash scripting | syntax error | conditional testing
Abstract: This article provides an in-depth analysis of the common '[: missing `]' error in Bash scripting, demonstrating through practical examples that the error stems from missing required spaces in conditional expressions. By comparing correct and incorrect syntax, it explains the grammatical rules of the test command and square brackets in Bash, including space requirements, quote usage, and differences with the extended test operator [[ ]]. The article also discusses related debugging techniques and best practices to help developers avoid such syntax pitfalls and write more robust shell scripts.
Problem Phenomenon and Error Analysis
In Bash script development, developers frequently encounter error messages like ./test.sh: line 13: [: missing `]'. This error message clearly indicates the problem: a missing right square bracket in the conditional test expression. However, the root cause is often more subtle than it appears.
Core Syntax Rules Analysis
Conditional testing in Bash is primarily implemented through two approaches: the traditional test command and its syntactic sugar form [ ]. Both forms have strict grammatical requirements, with the most critical being space separation.
Incorrect code example:
if [ -s "p1"]; # Error: missing space before right bracket
Correct code example:
if [ -s "p1" ]; # Correct: space separates parameter from right bracket
In Bash syntax, [ is actually a command (typically an alias for the test command), and ] is the last argument to that command. This means that [, test parameters, and ] must be separated by spaces, just like arguments to any other command.
Detailed Syntax Exploration
1. Traditional Test Syntax: The [ expression ] form requires:
- Space after
[ - Spaces between all parts of the expression
- Space before
] - The entire expression executes as an independent command
2. Extended Test Syntax: Bash also provides the [[ expression ]] form, which is a Bash keyword rather than a command, offering more flexible syntax:
if [[ -s "p1" && -r "p1" ]]; then
echo "File exists and is readable"
fi
Compared to [ ], [[ ]] supports more natural logical operators (like &&, ||) and pattern matching, though with slightly reduced portability.
Practical Case Debugging Process
Reviewing the script from the original problem:
#!/bin/bash
echo "Enter app name"
read y
$y &
top -b -n 1 > topLog.log
grep -w "$y" topLog.log > p1
if [ -s "p1"]; # Line 13: incorrect syntax
then
echo "Successful "
else
echo "Unsuccessful"
fi
rm p1
The incorrect syntax [ -s "p1"] on line 13 prevents the Bash parser from correctly identifying the command structure. The parser treats "p1"] as a single argument, then expects a right square bracket to terminate the [ command, but instead encounters a semicolon, resulting in the missing `]' error report.
Related Error Patterns and Solutions
Beyond missing spaces, other common error patterns include:
1. Incorrect Quote Usage:
if [ -s p1 ]; # Fails if filename contains spaces
if [ -s "p1" ]; # Correct: variables wrapped in quotes
2. String Comparison Errors:
if [ $var = "value" ]; # Fails if $var is empty
if [ "$var" = "value" ]; # Correct: variables quoted
3. Arithmetic Comparison Considerations:
if [ $a -gt $b ]; # Use -gt instead of >
if (( a > b )); # Or use arithmetic expansion
Debugging Techniques and Best Practices
1. Using the shellcheck Tool: ShellCheck can automatically detect such syntax errors:
$ shellcheck test.sh
In test.sh line 13:
if [ -s "p1"];
^-- SC1036: ']' needs to be separated from previous arg by whitespace.
2. Adding Debug Output: Include debugging information in complex conditional tests:
set -x # Enable debug mode
if [ -s "p1" ]; then
echo "Debug: file size is $(stat -c%s p1) bytes"
fi
set +x # Disable debug mode
3. Consistent Coding Standards:
- Always use spaces between
[, parameters, and] - Always quote variable references
- Consider using
[[ ]]for clearer logical expressions - Break complex tests into multiple simple tests
Conclusion and Further Reading
The space requirement in Bash conditional testing stems from understanding its command nature. [ as a command requires proper argument separation, which differs from syntax in most programming languages. Mastering this detail not only avoids missing `]' errors but also provides deeper insight into Shell script execution mechanisms.
For scenarios requiring more complex conditional logic, consider:
- Using
[[ ]]for string patterns and regular expression matching - Using
(( ))for arithmetic operations - Encapsulating complex logic in functions
- Noting portability differences between
[ ]and[[ ]]in cross-platform scripts
By understanding these syntax details, developers can write more robust, maintainable Bash scripts and avoid debugging difficulties caused by subtle syntax errors.