ksh中当前目录存在名为\的文件时变量处理行为异常原因问询
现象原因分析
- 首先明确Shell的展开执行顺序:未被双引号包裹的变量展开后,会依次执行字段拆分、路径名展开(通配符匹配),最后才会传递给命令作为参数。
- 赋值语句
x="\* a"中,双引号内的\后面跟着*,不属于双引号语境下需要转义的字符(仅$、`、"、\、换行符前的\才会被当作转义符处理),因此变量x实际存储的内容为字面量\* a。 - 执行
echo $x时没有加双引号,触发以下逻辑:- 变量展开得到字符串
\* a - 按IFS默认规则拆分得到两个独立字段:
\*、a - 对每个字段做路径名展开:
\*作为通配符模式,匹配所有以反斜杠开头的文件名
- 当目录下存在名为
\的文件时,该模式匹配成功,\*会被替换为匹配到的文件名\,最终传递给echo的参数为\和a,输出结果为\ a - 当目录下不存在匹配文件时,通配符模式保留原样,传递给echo的参数为
\*和a,输出结果为\* a
- 变量展开得到字符串
行为合规性说明
该行为完全符合ksh的预期设计,同时也符合POSIX标准定义的Shell语义规则,不属于程序Bug。
规避方案
要避免这类非预期的通配符展开问题,最佳实践是所有变量展开操作都包裹双引号,将示例代码改为echo "$x"即可,双引号会禁止字段拆分和路径名展开,始终输出变量的原始内容。
内容的提问来源于stack exchange,提问作者Tom K.
相关产品推荐
相关产品推荐

