为什么 shell 脚本中有双引号和反引号?

Sta*_*ann 5 shell shell-script quoting

我正在查看这个脚本 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`"
Run Code Online (Sandbox Code Playgroud)

更新:

"`${WHICH} gawk`"
Run Code Online (Sandbox Code Playgroud)

几乎一样

"${${WHICH} gawk}"
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 10

WHICH="`which which`"完全等同于WHICH=`which which`orWHICH=$(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)
Run Code Online (Sandbox Code Playgroud)

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

另见$VAR 与 ${VAR} 以及引用或不引用

  • @Andre:是的,`ECHO` 完全没用。但是所有对 `which` 的调用都没有用,因为脚本所做的只是调用命令,无论如何都会查找 `PATH`。引用也是关闭的:在这些变量的定义中有双引号,它们没有区别,但在使用变量时不会产生影响(有时它们甚至被“评估”)。你不能用命令名中的任何特殊字符来调用这个脚本(或在`$PASSWORD`中,但无论如何使用它都是一个坏主意)。 (4认同)