シェル スクリプトは、nano で保存すると機能しますが、Notepad++ で保存すると機能しません。

シェル スクリプトは、nano で保存すると機能しますが、Notepad++ で保存すると機能しません。

Notepad++ から SSH 内の nano エディターを使用して bash スクリプトを新しいファイルにコピーし、保存すると、正常に実行されます。(sh ./install)。

しかし、ファイルを保存し (まったく同じ内容)、Web サーバーにアップロードし、同じマシンで 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次のように、このスイッチをスクリプトの先頭のシェバン ( ) に組み込むこともできます。

#!/bin/bash -x

行末

これは、Windows から Unix/Linux システムにファイルを移動するときによく発生する問題です。この問題は、2 つのプラットフォームで行末がどのように示されるかに関係しています。詳細については、Wikipedia の次の記事を参照してください。改行

サンプルファイルを作成する

$ echo -e "This is a file.\nThat I made on Unix.\n" > unixfile.txt

@terdon が回答で説明しているように、sedこれらを削除するには を使用できますが、 と呼ばれるツールを使用してdos2unix同じことを行うこともできます。次の 2 つの方法のいずれかで使用できます。

$ dos2unix unixfile.txt

既存のファイルを上書きしたくない場合は、次のようにします。

$ dos2unix -n oldfile.txt newfile.txt

前述した上記の方法を使用すると、diff次の 2 つのファイルを比較したときに次のような出力が得られます。

$ 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 の回答では、 を使用して問題を解決する 1 つの方法が示されていますod。もちろん、さまざまな方法を使用して何が起こっているのかを把握できます。

vimの使用

cmdを使用しますfile

$ file unixfile.txt
winfile.txt: ASCII text 

$ file winfile.txt 
unixfile.txt: ASCII text, with CRLF line terminators

上記は、WindowsのファイルにCRLF(行末の復帰改行文字)が含まれているという問題を強調しています。これらの文字は16進数で0x0Dと0x0Aです。改行に関するWikipediaの記事もっと詳しく知りたい場合は。

vim問題を確認するには、次の方法も使用できます:

$ vim winfile.txt

vim問題を確認するために で何をすべきかを示す簡単なシーケンスを以下に示します。 CRLF 文字は通常、Unix では^M、つまりCtrl+として表示されますM

                                       vim の ss

winfile.txtこのシーケンスは、ファイルをフォーマットされた Unix ファイル ( ) として再度開くことを示しています:e ++ff=unix。これは、vimファイルが Windows 用にフォーマットされていることを自動検出しないように指示し、行終了文字を表示します^M

関連情報