Bash | Why should you put shell variables always between quotation marks ? (+ real world example)

kanames

Paladuta Stefan

Posted on July 26, 2023

Bash | Why should you put shell variables always between quotation marks ? (+ real world example)

This memo will help you understand how using quotation marks around shell variables can help ensure that they are interpreted correctly and can help avoid unexpected behavior.

You should put shell variables inside quotation marks to ensure that they are interpreted correctly by the shell. When you use a variable in a shell command or script without quotation marks, the shell will expand the variable, which means it will replace the variable with its value. This can cause problems if the variable contains spaces, special characters, or other characters that the shell interprets in a special way.

By enclosing the variable in quotation marks, you tell the shell to treat the entire string as a single argument, even if it contains spaces or other special characters. This can prevent errors and unexpected behavior in your shell commands and scripts.

For example, consider the following code:

MYVAR="Hello World"
echo $MYVAR
Enter fullscreen mode Exit fullscreen mode

Without quotation marks, Bash will split the value of MYVAR into two separate words, "Hello" and "World", and treat them as separate arguments to echo, resulting in the output:

Hello World
Enter fullscreen mode Exit fullscreen mode

However, if you put the variable in double quotes, like this:

MYVAR="Hello World"
echo "$MYVAR"
Enter fullscreen mode Exit fullscreen mode

The entire value of MYVAR is treated as a single argument to echo, resulting in the output:

Hello World
Enter fullscreen mode Exit fullscreen mode

Similarly, if your variable contains special characters such as asterisks or question marks, Bash will interpret them as globbing patterns and try to expand them into filenames in the current directory. This can lead to unexpected behavior or errors. Using quotes can prevent this behavior and ensure that the variable is treated as a literal string.

Therefore, it is generally a good practice to always put your shell variables inside double quotes unless you have a specific reason not to.

Real world example of bad management of quotation in shell scripting.

Consider the following scenario:

EX_VARIABLE="24/22/2021"
SQL_MSG=`sqlplus -s <user>/<pwd>@<db> <<-EOF
   whenever SQLERROR EXIT SQL.SQLCODE ROLLBACK;
   whenever OSERROR  EXIT SQL.SQLCODE ROLLBACK;

   select to_date('${EX_VARIABLE}','dd/mm/yyyy') from dual;

EOF`
if [ $? -eq 0 ]; then
   echo "OK";
else
   echo ${SQL_MSG}
fi
Enter fullscreen mode Exit fullscreen mode

The objective of this shell script is to check if the conversion from the string representation of a date (stored in the EX_VARIABLE variable) is working properly by evaluating whether it is a valid date.

# ./sh_example.sh

select to_date('24/22/2021','dd/mm/yyyy') from dual bin boot dev 
docker-entrypoint-initdb.d etc home lib lib64 media mnt 
opt proc root run sbin sh_example sh_example.sh srv sys tmp u01 
usr var ERROR at line 1: ORA-01843: not a valid month
Enter fullscreen mode Exit fullscreen mode

Image description

However, due to the lack of quotation marks around the SQL_MSG variable in the echo statement, the output includes extraneous information, such as the names of all the files in the current directory and if we check the content of the path where the shell is present:

Image description

we can see that the junk in fact represents all the files and logs from that specific folder !

  • bin
  • boot
  • dev
  • docker-entrypoint-initdb.d
  • etc
  • var
  • etc.

Reason of the behaviour

If we revisit the shell code again:

EX_VARIABLE="24/22/2021"
SQL_MSG=`sqlplus -s <user>/<pwd>@<db> <<-EOF
   whenever SQLERROR EXIT SQL.SQLCODE ROLLBACK;
   whenever OSERROR  EXIT SQL.SQLCODE ROLLBACK;

   select to_date('${EX_VARIABLE}','dd/mm/yyyy') from dual;

EOF`
if [ $? -eq 0 ]; then
   echo "OK";
else
   echo "${SQL_MSG}" #This was the only line of code changed
fi
Enter fullscreen mode Exit fullscreen mode

but this time we are going to rewrite the line “echo ${SQL_MSG}”, more specific the variabile ${SQL_MSG} with quotation marks and run the shell again:

root@9ea9fad92c38:/# ./sh_example.sh
select to_date('24/22/2021','dd/mm/yyyy') from dual
               *
ERROR at line 1:
ORA-01843: not a valid month
Enter fullscreen mode Exit fullscreen mode

Image description

we can see that this time it worked but what happened ?

Because the quotation marks were missing my theory is that the echo command tried to do echo of each of the lines that we see in the output:

  • echo select to_date(‘24/22/2021’,’dd/mm/yyyy’) from dual
  • echo * <- and echo * actually is a command that returns you the list of all the files and folder from the current directoy so the junk that we saw in red is actually the result of this command
  • echo ERROR at line 1:

If you liked the article please take a minute to offer me a clap 👏 or even buy me a coffee https://www.buymeacoffee.com/stefansplace (;

Original post: https://medium.com/@stefan.paladuta17/bash-why-should-you-put-shell-variables-always-between-quotation-marks-real-world-example-ac794dd53a84

💖 💪 🙅 🚩
kanames
Paladuta Stefan

Posted on July 26, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related