问题描述:
shell脚本从配置文件中读取IP,然后对读取IP进行处理,但是碰到一个问题,读取的IP,总是不正确。脚本很简单。将脚本与配置文件简化后发现一个奇怪的问题, 其实问题比较简单,只是没有注意到,导致分析了很长的时间,现记录下来。
bash 脚本如下
1
2
3
4
5
6
7
|
#
!/bin/bash
cur
=
`pwd`
filelist
=
`cat ${cur}/t
1
.txt `
for
line in ${filelist}
do
echo
"line ===========#${line}##"
done
|
其t1.txt的值也比较简单
执行脚本:
[
root@hadoop220 script]# ./test1.sh
##ne ===========#abc ------本来应该打印在abc后面的#,结果跑到前面去了。
[
root@hadoop220 script]#
分析:
之前怀疑读取的
${line}中
包含了其它不可见的字符。 刚开始使用ultraedit查看它的十六进制, 也没有发现有异常的情况。 在linux下面使用 vi打开t1.txt的时候,偶然发现它是DOS格式
尝试使用dos2unix转换了一下,测试OK
原因:
当文件是dos格式的时候,
换成人眼可读取字符,应该就是:abc[CR][LF] , CR
而当文件是unix格式的时候:
换成可读字符,就是: abc[LF]
到网上查看了下:
Dos和windows采用回车+换行CR/LF表示下一行,
而UNIX/Linux采用换行符LF表示下一行,
苹果机(MAC OS系统)则采用回车符CR表示下一行.
CR用符号'\r'表示, 十进制ASCII代码是13, 十六进制代码为0x0D;
LF使用'\n'符号表示, ASCII代码是10, 十六制为0x0A.
而UNIX/Linux采用换行符LF表示下一行,
苹果机(MAC OS系统)则采用回车符CR表示下一行.
CR用符号'\r'表示, 十进制ASCII代码是13, 十六进制代码为0x0D;
LF使用'\n'符号表示, ASCII代码是10, 十六制为0x0A.
因此当文本为DOS格式的时候:其存储的字符就是abc\r\n, 至此,我们就可以发现相对于UNIX格式的文件,DOS格式文件多了一个\r,而这个\r就是导致问题的出现。
[
root@hadoop220 script]# echo -e "abc\rmn"
mnc
[
root@hadoop220 script]#
最后附上从网上
http://blog.sina.com.cn/s/blog_4da051a6010184uk.html 找到的关于echo -e的几种特殊字符的处理
echo -e 处理特殊字符
若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:
\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\\ 插入\字符;
\nnn 插入nnn(八进制)所代表的ASCII字符;