Defensive Scripting, The Double Quote Way
If you want to ensure your shell script is fool-proof and that it will not break in all kind of situation, you should script it in a 'defensive' way. What I mean defensive is do not assume things. Often time people assume that their variable is set with non-empty value and they will try to use the variable value to compare with some pre-defined value. If the variable value is an empty string, your test condition will fall apart if it is not double quoted. Here I am going to simulate this type of situation where the 'ostype' variable will be empty because the command to run does not exist.
$cat c.sh #! /bin/sh ostype=`unknown_cmd_get_os` if [ $ostype = unix ]; then echo unix else echo windows fi echo here $./c.sh ./c.sh: line 4: unknown_cmd_get_os: command not found ./c.sh: line 6: [: =: unary operator expected windows here
In the above execution, the 'if' command thrown exception because shell carried out command and variable substitutions before the shell parsed the command line. Here are the steps the shell will go through
if [ $ostype = unix ]; then ...
is typed in before you hit the return button- Upon hitting the return button, the shell will do substitution and in our case it will do variable substitution by replacing the $ostype with it's value. So the command going to the shell will be
if [ = unix ]; then ...
- When shell read from the standard input, it knows that you are trying to run the "if" command
- The if" command is a built-in shell syntax and the correct syntax should be 'if' 'condition' 'then' .... 'fi'
- Syntax for 'condition' should be '[' 'expr' ']' , and 'expr' is a conditional expression
- What you want is to compare the value of variable "ostype" with the string "unix". However, after the variable substitution there isn't anything there and your 'expr' becomes '= unix' which is an incorrect conditional expression.
- Exception occurred.
To be 'defensive', you can do either the following:
- Double quote everything. As you can see, it does not break the if statement because you are comparing an empty string with the string "unix"
$
cat c.sh #! /bin/sh ostype=`unknown_cmd_get_os` if [ "$ostype" = "unix" ]; then echo unix else echo windows fi echo here $ ./c.sh ./c.sh: line 4: unknown_cmd_get_os: command not found windows here - Prepend some arbitrary character(s), in our case a character 'x', to ensure the string is non-empty. With this technique you do not necessarily need to double quote the string
$
cat c.sh #! /bin/sh ostype=`unknown_cmd_get_os` unix="unix" if [ x$ostype = x$unix ]; then echo unix else echo windows fi echo here $./c.sh ./c.sh: line 4: unknown_cmd_get_os: command not found windows here
IMHO, the best practice will be to double quote all your string. So next time when you script your string comparison, remember to double quote them.
Labels: shell script
1 Comments:
Good intro to shell quoting and pitfalls
Post a Comment
<< Home