Bash Shell Scripting Triple Play Part 1

1) Never use do this:

PATH="/home/researcher/Documents/"

Why? Well, it wasn’t apparent to me what was going wrong with my program when it was telling me that it could not find the find command:

line 15: find . -name core.* -printf '%f\n': command not found

… but after a ton of trying different things I realized that I stomped out the environment variable $PATH that told the shell where to look for the programs I called. Change it to DOC_PATH or something else and you’re off to the races.

2) There are two ways to execute shell commands inside a shell script — either of which can be used to redirect the output into a script variable:

CMD="find / -name *.log | grep -v startup"

# Way 1: Enclose command variable in $(...)
RES_1=$(${CMD})

# Way 2: Enclose command in backticks (under tilde)
RES_2=`${CMD}`

Apparently, they’re exactly the same, but it would seem that enclosing it in the $(…) wrapper would give you allow you to avoid the confusing ` vs ‘ vs ” at least a little more often.

3) It is always a good idea to enclose your variables with double quotes. This is extremely important when using echo.
So:

CMD="find / -name *.conf"
echo ${CMD}

RES_SET=$(${CMD})
echo ${RES_SET}

…becomes:

CMD="find / -name *.conf"
echo "${CMD}"

RES_SET=$(${CMD})
echo "${RES_SET}"

You’ll not that I don’t enclose the variable in any quotes when I pass it to the subshell to be executed — it ends up that that doesn’t work and the shell executing the script complains about the command.

Consider this example demonstrating the difference:

#!/bin/bash

PTH="/home/elite/"

CMD="ls ${PTH} -l"
echo ${CMD}
echo "${CMD}"

RES=$(${CMD})
echo ${RES}
echo "${RES}"

… which gets you:

[elite@thehost elite]# ./temp
ls /home/elite/ -l
ls /home/elite/ -l
total 38988 -rwxrwxr-x 1 elite elite 521 2009-10-01 00:42 area -rwxrwxr-x 1 elite elite 921 2009-09-28 01:21 gs.sh -rw-rw-r-- 1 elite elite 62 2009-09-28 01:22 plugin.txt drwxrwxr-x 7 elite elite 4096 2009-09-30 22:10 Documents -rw-rw-r-- 1 elite elite 1850 2009-09-29 22:20 startup.log -rw------- 1 elite elite 255812 2009-09-30 22:08 valgrind1.log -rw------- 1 elite elite 39595684 2009-10-01 00:43 valgrind2.log
total 38988
-rwxrwxr-x 1 elite elite      521 2009-10-01 00:42 area
-rwxrwxr-x 1 elite elite      921 2009-09-28 01:21 gs.sh
-rw-rw-r-- 1 elite elite       62 2009-09-28 01:22 plugin.txt
drwxrwxr-x 7 elite elite     4096 2009-09-30 22:10 Documents
-rw-rw-r-- 1 elite elite     1850 2009-09-29 22:20 startup.log
-rw------- 1 elite elite   255812 2009-09-30 22:08 valgrind1.log
-rw------- 1 elite elite 39595684 2009-10-01 00:43 valgrind2.log

Note that the commands seemed to echo identically with our without the double quote encapsulation. The same cannot be said for the result, however. The result variable not enclosed in double quotes lost its formatting characters, namely the newline characters and multiple spaces.

Posted Thursday, October 1st, 2009 under shell scripting, tips and tricks.

Leave a Reply