目录
字符串比较的最优形式 — 冗余常量(x) + “SHELL变量”
Shell 脚本的比较判读语句,一种是使用 test 命令,一种是使用中括号形式 [ ]
,脚本根据比较的结果进行后续动作。其中,一个比较常见、也容易出错的场景是,一个变量值与常量进行比较,如
if test $SHELL_VAR = yes;
或
if [ $SHELL_VAR = yes ]
使用如上的原生态比较方法,由于 SHELL_VAR
取值的多样化,一些特定的变量取值会造成脚本错误或后续执行逻辑的偏离。规避这一问题的最佳方法是,使用 “冗余常量与双引号 SHELL 变量联合字符串” 的方法,即使用 x"$SHELL_VAR"
的形式代替原来的 $SHELL_VAR
形式。
错误使用1:不使用双引号 “”,不使用前缀 x
有变量 SHELL_VAR
未定义($SHELL_VAR为空)
if test $SHELL_VAR = yes; then
-->
if test = yes; then
显然是有语法错误,test 丢失参数。
错误使用2:不使用双引号 “”,仅仅使用前缀 x
$SHELL_VAR
值为空
if test x$SHELL_VAR = yes; then
-->
if test x = yes; then
看似看着是没有问题的。但是假如此时 $SHELL_VAR
值为” yes”,即 yes 前面有一个空格,则
if test x$SHELL_VAR = yes; then
-->
if test x yes = yes; then
显然,这样也是有语法错误的,test有两个参数 x 和 1(yes=yes)。
错误使用3:仅仅使用双引号 “”,不使用前缀 x
$SHELL_VAR
值为空
if test "$SHELL_VAR" = "yes"; then
-->
if test "" = "yes"; then
$SHELL_VAR
值为 ” yes”
if test "$SHELL_VAR" = "yes"; then
-->
if test " yes" = "yes"; then
貌似使用 “” 把变量包起来就没有问题了。但是假如此时$SHELL_VAR值为“-n”或者 “-f”
if test "$SHELL_VAR" = "yes"; then
-->
if test "-f" = "yes"; then
则此时 "-f"
是有二义性的,是作为 test 命令的 option 还是 test 的 argument ?
正确使用:使用双引号 “”,使用前缀 x
$SHELL_VAR
值为空
if test x"$SHELL_VAR" = x"yes"; then
-->
if test x"" = x"yes"; then
$SHELL_VAR
值为 ” yes”
if test x"$SHELL_VAR" = x"yes"; then
-->
if test x" yes" = x"yes"; then
$SHELL_VAR
值为 “-n” 或者 “-f”
if test x"$SHELL_VAR" = x"yes"; then
-->
if test x"-f" = x"yes"; then
在 Linux 的系统脚本中,可以常见这种用法。
这类问题,尤其是比较中的变量调用的是脚本输入参数时,如 $1
、$2
,如果使用错误的比较形式,某种程度上也可视为针对 Shell 脚本的一种注入攻击。