web-dev-qa-db-ja.com

Windowsで編集されたBash / Kornシェルスクリプトがエラー「... ^ M:見つかりません」をスローする

Notepad ++を使用してWindowsでBashスクリプトを記述しました。

cxStopAllServicesOnSERVER.sh

#!/usr/bin/bash
cd "/some/path"
echo "Hi. Logs can be found at "`pwd`"/cxStartStopLogger.log"
echo "["`date`"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"
exit

それをアップロードして必要なファイル権限を設定した後、次のように実行してみました。

bash-3.00$ cat cxStopAllServicesOnSERVER.sh #Let's have a look at the code.
#!/usr/bin/bash
cd "/some/path/"
echo "Hi. Logs can be found at "`pwd`"/cxStartStopLogger.log"
echo "["`date`"]*** STOPPING ALL SERVICES ON SERVER ***" >> "cxStartStopLogger.log"

bash-3.00$ # Code and hashbang 'looks' correct, 
bash-3.00$ # if there is any issue with the format (EOL characters and such) 
bash-3.00$ # we cannot see it using cat.
bash-3.00$ 
bash-3.00$ sh cxStopAllServicesOnSERVER.sh
cxStopAllServicesOnSERVER.sh[2]: /some/path^M:  not found
Hi. Logs can be found at /some/path/cxStartStopLogger.log
bash-3.00$ # Note that ^M appears at the end of the line.

bash-3.00$ bash -x cxStopAllServicesOnSERVER.sh
+ cd $'/some/path\r'
: No such file or directory1.sh: line 2: cd: /some/path
++ pwd
' echo 'Hi. Logs can be found at /some/path/cxStartStopLogger.log
Hi. Logs can be found at /some/path/cxStartStopLogger.log
++ date
+ echo '[Sun' Nov 18 00:28:17 EST '2012]*** STOPPING ALL SERVICES ON SERVER ***'
bash-3.00$ # Note that '\r' return character appears at the end of the line.

問題:コードをKornシェルに変更すると、同じ問題が発生します。行末に不正な文字が追加されているようです。

注:解決策を見つけ、同じ回答を投稿しました。同じ問題に直面する可能性がある他の初心者を助けるために、それを更新または改善してください。ありがとう!

8
Kent Pawar

さまざまなフォーラムといくつかのStack-overflow投稿を調べた後、問題が見つかりました。

エラーの根本的な原因をよりよく理解し、「確認」するための説明を次に示します。

まず、Windowsでコードを記述している場合は、Notepad ++を使用してください。私の意見では、それは基本的にテキストエディターのスイスアーミーナイフです。

EOL(行末)文字とその他の制御記号を確認するには、次のようにします。

1. Notepad ++でファイルを開きます。

メニューバーから[表示]> [記号を表示]> [すべての文字を表示]を選択します。

次のようなシンボルが表示されます。 Screenshot of Notepad++:Editing a UNIX script on Windows

ああ! Windows/MS-DOSはCR + LFを使用して行末を示します。 UNIXでは、LF文字を使用して行の終了(EOL文字)を示しています。

2.1 Windows EOLをUNIX EOLに変換しましょう:

[編集]> [EOL変換]> [UNIX形式]を選択します。

次のようなものが表示されます。

Screenshot of Notepad++: EOL Conversion to UNIX Format これが、行の終わりに「\ r」文字が追加される理由を説明しています。これは、UNIXが '\ n'またはLF(linefeed)を行終了/ EOL文字として認識したが、 '\ r'または^ M(復帰)文字を無視したためです。

EOLの問題をテストすることもできます

bash-3.00$ head myScript.sh | cat -vet | head -1
#usr/bin/bash^M$
bash-3.00$ #We see that ^M, that is \r is found at the end of each line. 

2.2。UNIXでファイルをWindowsからUNIX EOL形式に変換する場合は、これを修正する方法が2つあります。

$ dos2unix myScript.sh

または

@ Chris Downによって提供されるソリューションを以下のように使用します。

$ sed -i 's/\r$//' myScript.sh

参照:

  1. 行終端 および what-is-the-difference-between-r-and-n の詳細については、これらのリンクを参照してください。
15
Kent Pawar

スクリプトにはCRLF行末が含まれていますが、UnixではLF行末を使用しています。 GNU sedがある場合、以下はそれらを削除します。

sed -i 's/\r$//' cxStopAllServicesOnSERVER.sh

GNU sedがない場合は、一時ファイルに書き込んでから、古いファイルの上に移動します。

余談ですが、shを使用してスクリプトを呼び出すと、シバンをオーバーライドします。それはおそらくあなたが望むものではありません。

4
Chris Down