Shell – Why the double quotes and backquotes in a shell script

quotingshellshell-script

I'm looking at this script mysql backup script and I don't understand what is the reason for using both backticks and double quotes around command names?

379 WHICH="`which which`"
380 AWK="`${WHICH} gawk`"
381 LOGGER="`${WHICH} logger`"
382 ECHO="`${WHICH} echo`"
383 CAT="`${WHICH} cat`"
384 BASENAME="`${WHICH} basename`"
385 DATEC="`${WHICH} date`"
386 DU="`${WHICH} du`"
387 EXPR="`${WHICH} expr`"
388 FIND="`${WHICH} find`"
389 RM="`${WHICH} rm`"
390 MYSQL="`${WHICH} mysql`"
391 MYSQLDUMP="`${WHICH} mysqldump`"
392 GZIP="`${WHICH} gzip`"
393 BZIP2="`${WHICH} bzip2`"
394 CP="`${WHICH} cp`"
395 HOSTNAMEC="`${WHICH} hostname`"
396 SED="`${WHICH} sed`"
397 GREP="`${WHICH} grep`"

Update:

Is

"`${WHICH} gawk`"

pretty much the same as

"${${WHICH} gawk}"

Best Answer

WHICH="`which which`" is exactly equivalent to WHICH=`which which` or to WHICH=$(which which) or to WHICH="$(which which)". All of these run the command which which, and capture its output (as a string) into the variable WHICH, stripping off any final newline from the output. Similarly, AWK="`${WHICH} gawk`" could be written AWK=`$WHICH gawk`.

Normally, command substitutions (`command` or $(command)) should be surrounded by double quotes, in case the result contains whitespace or shell wildcards (*?[\). This is because the result of command substitutions, like variable substitutions ($foo or ${foo}), undergoes word splitting and filename generation (a.k.a. globbing). However, this does not apply to simple variable assignments: since the context requires a single word, the result of the substitution is taken as-is. So assignments are an exception to the general rule that you should double-quote variable and command substitutions. (Note that this exception does not extend to export var="$value", which does require the double quotes.) But it's a reasonable shell programming practice to always the double quotes — omit them only if you know you must, rather than using them only if you know you must.

In the (unlikely) case which which returns a path with spaces or wildcards, ${WHICH} should be double-quoted in the lines below, i.e. one of

AWK="`"${WHICH}" gawk`"
AWK=`"${WHICH}" gawk`
AWK="$("${WHICH}" gawk)"
AWK=$("${WHICH}" gawk)

(Using $(…) is recommended over `…`, because of the difficulty of getting the nested quoting right inside `…`. However very old shells don't recognize $(…), so `…` is needed for scripts that must run on older systems.)

See also $VAR vs ${VAR} and to quote or not to quote

Related Question