Shell脚本中export变量输出异常问题求助
我看你在Shell脚本里导出变量时遇到了奇怪的问题——明明定义了BASE_LOCATION,但拼接后的EXT_LIB输出不对,只显示了/li...这类截断的内容。先把你的代码贴出来方便复盘:
export BASE_LOCATION=/home/hduser/hdm export EXT_LIB=$BASE_LOCATION/extlib echo $EXT_LIB export EXT_LIB_JARS=$EXT_LIB/common-csv-1.1.jar:$EXT_LIB/spark-csv_2.10-1.5.0.jar echo $EXT_LIB_JARS
你预期echo $EXT_LIB输出/home/hduser/hdm/extlib,但实际只得到了截断的内容,对吧?
可能的原因分析
这种截断通常是因为变量里包含了不可见的控制字符,比如回车符\r(Windows风格的换行符)。如果你的脚本是在Windows环境下编辑的,然后传到Linux/Unix系统里,就很容易出现这个问题——Windows的换行是\r\n,而Linux是\n,多余的\r会导致输出时光标跳回到行首,后面的内容覆盖了前面的部分,看起来就像是截断了。
举个例子,如果BASE_LOCATION的值实际是/home/hduser/hdm\r,那么$BASE_LOCATION/extlib就会变成/home/hduser/hdm\r/extlib,当你echo的时候,\r会让光标回到行开头,接着输出/extlib,就会覆盖掉前面的部分,最终显示成/extlib(或者你看到的/li...,取决于具体长度)。
解决方法
1. 清除脚本中的Windows换行符
用dos2unix命令转换脚本格式:
dos2unix your_script.sh
如果没有dos2unix,也可以用sed命令替换掉\r:
sed -i 's/\r$//' your_script.sh
2. 手动检查并修正变量定义
打开脚本时用支持显示控制字符的编辑器(比如vim,开启:set list模式可以看到^M表示\r),把所有行尾的^M删掉。
3. 验证变量是否干净
在使用变量前,可以先输出变量的十六进制格式来检查是否有异常字符:
echo -n $BASE_LOCATION | xxd
正常情况下应该只有路径的ASCII码,不会出现0d(对应\r)的字节。
验证修复效果
修复后重新运行脚本,echo $EXT_LIB应该就能正确输出/home/hduser/hdm/extlib,后续的EXT_LIB_JARS也会正常拼接了。
内容的提问来源于stack exchange,提问作者Adarsh

