file命令查看檔案屬性為*.sh ASCII text, with CRLF line terminators
Linux和Windows文字檔的行結束標誌不同。在Linux中,文字檔用"/n"表示斷行符號換行,而Windows用"/r/n"表示斷行符號換行。有時候在Windows編寫shell指令碼時需要注意這個,否則shell指令碼會報"No such file or directory"或"command not found line x"之類的錯誤,如果不知曉前因後果,肯定會被這個折騰得相當鬱悶。如下所示test.sh
[root@DB-Server myscript]# more test.sh
. /home/oracle/.bash_profile
echo ' '
date
echo ' '
sqlplus test/test @/home/oracle/scripts/test.sql
echo ' '
date
echo ' '
執行test.sh指令碼過程中報" No such file or directory /home/oracle/.bash_profile" 和"command not found line xx". 如果你從shell指令碼文法方面去檢查,根本沒有任何問題。不知具體原因的肯定相當鬱悶。
[oracle@DB-Server myscript]$ ./test.sh
: No such file or directory /home/oracle/.bash_profile
: command not found line 2:
: command not found line 4: date
: command not found line 6:
: command not found line 7:
如果你用file命令查看test.sh,你會發現檔案編碼為ASCII,with CRLF line terminators。我們用cat -v test.sh 可以看到^M (\r的十六進位為0D,對應的控制符為^M)。 cat -v可以看到檔案中的非列印字元。
[root@DB-Server myscript]#
[root@DB-Server myscript]# file test.sh
test.sh: ASCII text, with CRLF line terminators
[root@DB-Server myscript]# cat -v test.sh
. /home/oracle/.bash_profile^M
echo ' '^M
date^M
echo ' '^M
^M
sqlplus test/test @/home/oracle/scripts/test.sql^M
^M
echo ' '^M
date^M
echo ' '^M
[root@DB-Server myscript]#
vi命令查看test.sh檔案看不到^M, 其實這個跟vi的版本有關係。有些版本vi顯示的是行尾為^M(AIX下都是顯示^M)。而有些vi開啟時可以看到底下有[dos]的格式提示。
我們可以用file命令對比正常的shell指令碼的格式和編碼。如下所示
[oracle@DB-Server myscript]$ file myshell.sh
myshell.sh: Bourne-Again shell script text executable
解決這個問題其實也不難,有很多方式,例如直接使用vi編輯器編寫shell指令碼;使用cat命令建立shell指令碼,然後從Windows文本工具裡面拷貝指令碼過來;最方便的還是使用dos2unix將DOS格式文字檔轉換成Unix格式或Linux格式。