Bash异常状态求助:多单词字符串被识别为单个单词的原因及恢复方法
Bash异常状态求助:多单词字符串被识别为单个单词的原因及恢复方法
看起来你的bash shell大概率是内部字段分隔符(IFS)被意外修改了——这是导致read -a无法正确拆分多单词字符串的最常见原因。
问题根源分析
bash默认的IFS(Internal Field Separator)包含空格、制表符和换行符,read -a正是依赖这些字符来把输入字符串拆分成数组元素。如果IFS被改成了不包含空格的值(比如被设为空,或者其他非空白字符),read就会把整个输入字符串当作单个数组元素处理,这就出现了你看到的“三个单词被识别成一个”的异常情况。
另外你提到stty -g输出有差异,但stty管的是终端的输入输出行为(比如回显、换行),和bash内部的字段分割逻辑无关,所以tset/reset这类重置终端的命令解决不了问题。
验证方法
在那个异常的bash窗口里运行下面的命令,查看当前IFS的实际值:
printf "%q\n" "$IFS"
正常情况下应该输出类似$' \t\n'(代表空格、制表符、换行符)。如果输出是空字符串、或者其他奇怪的内容,就坐实了IFS被篡改的问题。
恢复bash正常状态的方法
直接重置IFS为默认值,有两种简单方式:
- 手动设置默认
IFS:
IFS=$' \t\n'
- 直接取消
IFS的自定义设置(bash会自动恢复默认值):
unset IFS
运行完上面任意一条命令后,再重新执行你的测试代码:
WEy="a b c"; read -a WEarr <<< "$WEy"; WE_noe=${#WEarr[@]}; echo "WE_noe: ~$WE_noe~"; for ((i=0; $i<$WE_noe; i++)); do echo "$i:: ${WEarr[$i]}"; done
应该就能得到正确的输出了:
WE_noe: ~3~ 0:: a 1:: b 2:: c
额外提醒
这种情况通常是误操作(比如不小心执行了IFS=","这类命令)、或者某个脚本修改了IFS但没有恢复导致的。如果之后频繁出现这个问题,可以检查下你的~/.bashrc、~/.bash_profile这类启动脚本里有没有意外修改IFS的代码。
备注:内容来源于stack exchange,提问作者Anton Wessel
相关产品推荐
相关产品推荐

