當我將 Notepad++ 中的 bash 腳本複製到 SSH 內使用 Nano 編輯器的新檔案並儲存。它運行良好。 (sh ./安裝)。
但是,如果我保存檔案(完全相同的內容),上傳到我的網頁伺服器,然後在同一台電腦上使用 Wget 下載它。我收到語法錯誤。我檢查了編碼,它們似乎是相同的。此後我使用了大量的字元編碼來查看是否可以解決該問題。當我使用 wget 下載該檔案後,我還將該檔案設定為可執行檔!
該文件運作良好,並且使用 nano 複製和貼上時出現零錯誤。知道這可能是什麼嗎?
答案1
我願意打賭該問題與行結尾有關。您可能正在沿線的某個地方使用非 *nix 機器。我還遇到過一個問題,apache
(在 Linux 上運行)向上傳的文本文件添加 Windows 樣式的行結尾,因此您可能會看到類似的內容。
要進行測試,請取得您下載的檔案並將其傳遞給od
.如果它是一個長文件,只需抓住前幾行:
head script.sh | od -c
查看輸出並檢查是否有類似以下內容:
f o o \r \n
這是一個回車符,在 Windows 上,行以*nix不同的方式\r
結束。如果事實證明這確實是問題所在,您可以透過刪除回車符來修復檔案:\r\n
\n
sed -i 's/\r//g' script.sh
答案2
正如@graeme 敏銳地指出的那樣,由於伺服器上有兩種形式的腳本,因此您可以執行簡單的操作diff
來確定工作版本和有問題的版本之間的不同之處。
$ diff working.sh broken.sh
您也可以像這樣進行並排比較:
$ diff -y working.sh broken.sh
如果腳本因某種拼字錯誤而無法運作,您通常可以透過將-x
開關新增至 來偵測這些錯誤bash
,這會導致腳本變得冗長。
$ bash -x broken.sh
#!/bin/bash
您也可以將此開關合併到腳本頂部的shebang ( ) 中,如下所示:
#!/bin/bash -x
行結尾
將檔案從 Windows 移至 Unix/Linux 系統時,這通常是問題。該問題與兩個平台上如何表示行尾有關。您可以在維基百科上閱讀更多相關信息,標題為:換行符。
製作一個樣本文件
$ echo -e "This is a file.\nThat I made on Unix.\n" > unixfile.txt
正如 @terdon 在他的回答中所描述的,您可以使用它sed
來刪除這些內容,您也可以經常使用名為 的工具dos2unix
來執行相同的操作。您可以透過以下兩種方式之一使用它:
$ dos2unix unixfile.txt
或者如果您不想覆蓋現有文件:
$ dos2unix -n oldfile.txt newfile.txt
當您使用我之前提到的上述內容時,diff
當您比較這兩個文件時,您將得到以下輸出:
$ diff -y unixfile.txt winfile.txt
This is a couple | This is a couple
of lines of sample | of lines of sample
text. | text.
您將無法辨別差異,只是它們確實存在。 @terdon 的答案再次展示了一種使用 解決問題的方法od
。當然,您可以使用多種方法來弄清楚發生了什麼。
使用vim
與file
cmd。
$ file unixfile.txt
winfile.txt: ASCII text
$ file winfile.txt
unixfile.txt: ASCII text, with CRLF line terminators
上面強調了這個問題,即 Windows 中的檔案具有 CRLF(又稱:行尾的回車符 + 換行符)。這些字元是十六進位的 0x0D 和 0x0A,再次參見維基百科關於換行符的文章如果你想了解更多。
您也可以使用vim
來查看問題:
$ vim winfile.txt
以下是一個小序列,展示如何vim
查看該問題。 CRLF 字元通常在 Unix 中顯示為^M
,即Ctrl+ M。
該序列顯示我重新打開該文件,winfile.txt
作為格式化的 Unix 文件 ( :e ++ff=unix
)。這告訴vim
不要自動偵測文件的格式是否適用於 Windows,因此它將顯示^M
行終止字元。