在一次偶然的事件中,我複製了一段EOF代碼粘貼到腳本的另一位置,結果腳本就不運行了。後來通過排查發現原來是空格的問題。下面舉例說明這個問題。
首先看如下腳本
# vim bb.sh
#!/bin/bash echo test if [ $? -eq 0 ];then echo "aa" else cat >aa <<-EOF 6 EOF echo "bb" fi echo $?
# ./bb.sh
test
aa
0
腳本執行成功,一切正常。
現在我們做兩個操作,比較下異同。
操作一:在vim中複製以下代碼段粘貼到if的else上方。
cat >aa <<-EOF 6 EOF
完成後代碼如下:
#!/bin/bash echo test if [ $? -eq 0 ];then echo "aa" cat >aa <<-EOF 6 EOF else cat >aa <<-EOF 6 EOF echo "bb" fi echo $?
# ./bb.sh
test
aa
0
# cat aa
6
一切執行正常,aa文件也被寫入了EOF中的數值6
操作二:我們不用vim的yy命令去複製,而是改用xhell的鼠標複製功能,用鼠標選定這三行,再粘貼到上面的else上方。
粘貼後代碼如下:
#!/bin/bash echo test if [ $? -eq 0 ];then echo "aa" cat >aa <<-EOF 6 EOF else cat >aa <<-EOF 6 EOF echo "bb" fi echo $?
看上去與yy複製的並沒有什麼不同。
那麼我們執行一下看看。
# ./bb.sh
test
aa
bb
0
得到的結果完全出乎意料,可以看到if命令已經失效了,echo "aa" echo "bb"都被執行了!
# cat aa
6
EOF
else
cat >aa <<-EOF
6
再看輸入的aa文件,也不是想要的結果6!而是前後兩個EOF之間的字段
那麼這是爲什麼?
原因就在於空格和tab的問題!
在vim下我們用:set list來顯示特殊字符
下圖是操作一,即用yy命令複製時的代碼圖
下圖是操作二,即用鼠標複製時的代碼圖
發現兩者的不同沒有?
操作一中yy複製的三行和原來的三行格式一樣,EOF結尾符前面是^I,即tab字符。
操作二中鼠標複製的三行和原來的三行格式不一樣,EOF結尾符前面是空格,不是tab!
結論:
重定向-EOF只會匹配前面以tab開頭的EOF結束符,而不會匹配空格開頭的EOF,操作二中,由於第一個EOF前面是空格,不會被識別爲結束標誌,而是被當作一個輸入的字符來對待,當遇到第二個EOF時,由於前面是tab鍵,就被匹配爲結束字符,所以也就出現了aa文件中的那一大串字符。