在Shell中输入hql="select * from b_table"; hive -e $hql; 提示执行失败,逐步排查发现hql变量中的“*”已经被替换成一串字符串,该字符串正是当前目录下的一系列文件名。由此可以联想到正则表达式中的万能匹配符“*”,例如以下代码也将输出当前目录下的文件名称。
echo *
>bin boot dev etc home lib lib64 media mnt opt root sbin sys tmp usr var
那么如何才能使得引用变量中的星号符保持它原来的面目?《ABS Guide》是这么解释引用(引号)的:
引号的特殊效果就是,保护字符串中的特殊字符不被 Shell 或者是 Shell 脚本重新解释或者扩展。(我们这里所说的“特殊”指的是一些字符在Shell中具有的特殊意义,比如“*”);在我们一般的生活中,引号内的内容往往有特殊的含义,而在 Bash 中,当我们引用一个字符串,我们是保护它的字面含义。
在一个双引号中直接使用变量名,一般都是没有问题的。它阻止了所有在引号中的特殊字符的重新解释:包括变量名,但是($),(`)和(\)除外。保留($)作为特殊字符的意义是为了能够在双引号中也能够正常地引用变量,像这样"$var",这样在""中可以使用变量所表达的值。而双引号可以防止通配符扩展但允许变量扩展(链接)。
hql="select * from b_table" # 定义变量
echo "$hql"
>select * from b_table # 双引号“引用”$变量名,保持“变量所表达的值”的原本面目
echo '$hql'
>$hql # 单引号“引用”$变量名,直接打印单引号所包裹的内容
echo $hql
>select bin boot dev etc home lib lib64 media mnt opt root sbin sys tmp usr var from b_table # 不使用引号,则$hql中的*将类似上例中那样被当前目录中的文件名字符串所替代
这样理一遍清楚了许多。但是当时为什么不用以下更加直观的代码而非要定义个变量,现在也觉得不可思议;印象中当时用该语句时*也被替换成文件名字符串了,囧。
hive -e "select * from b_table"
如果文章对你有用,请在收藏之余“顶/赞”一下以示鼓励吧 (/ω\)