Linux Shell中IFS分割字符串时通配符被替换的原因及解决方法
IFS分割字符串时通配符被展开的问题分析与解决
原因
问题出在temp_str=($STRING)这一行:
- Shell默认会对不带引号的变量展开执行路径扩展(通配符匹配),
*.py会被替换成当前目录下所有匹配该模式的文件名(这里就是test.py)。 - 即使你修改了IFS为
|,不带引号的变量展开会同时触发单词分割(按IFS分割)和路径扩展,这两个都是Shell的默认行为,导致*.py被意外替换。
解决方法
方法一:使用read命令分割(推荐)
利用read -a命令按指定IFS分割字符串到数组,同时通过双引号包裹变量避免通配符扩展:
OLD_IFS=${IFS} echo -e "OLD_IFS: ${OLD_IFS}" IFS='|' echo -e "IFS: ${IFS}" STRING="HELLOWORLD|*.py" # -r 禁用反斜杠转义,-a 将分割结果存入数组 read -r -a temp_str <<< "$STRING" IFS=${OLD_IFS} echo -e "IFS: ${IFS}" echo -e "${temp_str[0]}" echo -e "${temp_str[1]}"
方法二:临时关闭路径扩展
用set -f禁用通配符扩展,完成数组赋值后再恢复:
OLD_IFS=${IFS} echo -e "OLD_IFS: ${OLD_IFS}" IFS='|' echo -e "IFS: ${IFS}" # 关闭路径扩展 set -f STRING="HELLOWORLD|*.py" temp_str=($STRING) # 恢复路径扩展 set +f IFS=${OLD_IFS} echo -e "IFS: ${IFS}" echo -e "${temp_str[0]}" echo -e "${temp_str[1]}"
注意事项
在Shell中处理变量时,除非明确需要触发通配符或单词分割,否则尽量用双引号包裹变量,避免意外的展开行为。
内容的提问来源于stack exchange,提问作者qiaochu li
相关产品推荐
相关产品推荐

