为什么 shell 脚本中要使用双引号和反引号?

为什么 shell 脚本中要使用双引号和反引号?

我正在看这个脚本 mysql备份脚本我不明白在命令名称周围使用反引号和双引号的原因是什么?

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`"

更新:

"`${WHICH} gawk`"

几乎一样

"${${WHICH} gawk}"

答案1

WHICH="`which which`"完全等同于WHICH=`which which`or toWHICH=$(which which)或 to WHICH="$(which which)"。所有这些都运行命令which which,并将其输出(作为字符串)捕获到变量中WHICH,从输出中去除任何最终的换行符。同样,AWK="`${WHICH} gawk`"可以写成AWK=`$WHICH gawk`.

通常,命令替换 (`command`$(command)) 应该用双引号引起来,以防结果包含空格或 shell 通配符 ( *?[\)。这是因为命令替换的结果(如变量替换($foo${foo}))会经历分词和文件名生成(也称为通配符)。然而,这不适用于简单的变量赋值:由于上下文需要单个单词,因此替换的结果按原样采用。因此,赋值是一般规则的一个例外,即您应该用双引号变量和命令替换。 (请注意,此异常不会扩展到export var="$value",它确实需要双引号。)但始终使用双引号是一种合理的 shell 编程实践 — 仅当您知道必须时才省略它们,而不是仅当您知道必须时才使用它们。

在(不太可能)情况下which which返回带有空格或通配符的路径,${WHICH}应在下面的行中用双引号引起来,即以下之一

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

$(…)建议使用 超过`…`,因为很难在 内部获得嵌套引用`…`。但是非常旧的 shell 无法识别$(…),因此`…`必须在旧系统上运行的脚本需要使用 。)

也可以看看$VAR 与 ${VAR} 以及引用或不引用

答案2

如果反引号返回一个包含空格的字符串。引号确保将完整的单个值分配给变量。

答案3

反引号运算符的意思是“用反引号内找到的命令的输出替换反引号之间的区域。双引号就是这样,如果该输出包含空格,则相关变量将被设置为完整结果,而不仅仅是所有结果第一个空白。

例如,如果由于某种原因你的 grep 命令是 '/usr/local/bin/real grep',执行后,

GREP=`which grep`

GREP 将包含“/usr/local/bin/real”

鉴于,

GREP="`which grep`"

GREP 将包含“/usr/local/bin/real grep”。

这些命令的任何路径不太可能包含空格,但 shell 脚本编写中的一般良好做法是在分配给变量时始终使用双引号。

相关内容