Shell 腳本在使用 nano 儲存時有效,但在使用 Notepad++ 儲存時無效

Shell 腳本在使用 nano 儲存時有效,但在使用 Notepad++ 儲存時無效

當我將 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

filecmd。

$ 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

                                       vim 的 ss

該序列顯示我重新打開該文件,winfile.txt作為格式化的 Unix 文件 ( :e ++ff=unix)。這告訴vim不要自動偵測文件的格式是否適用於 Windows,因此它將顯示^M行終止字元。

相關內容