私はこのスクリプトを持っています:
echo $HOME
cd $HOME
cd /
cd /usr/local/src/
このように実行すると
. script.sh
私はこの出力を取得します:
/home/user
: No such file or directory
: No such file or directory
: No such file or directory
正常に実行した場合(最初の行の前に#!/bin/bash
を追加しました)
sh script.sh
私はこの出力を取得します:
: not found.sh: 2: script.sh
/home/user
script.sh: 3: Can't cd to /home/user
script.sh: 4: Can't cd to /
script.sh: 5: Can't cd to /usr/local/src/
スクリプトは$HOME
ディレクトリから毎回実行されました。シェルから各コマンドを1つずつ実行すると、問題なく実行されました(cd $HOME
内から$HOME
を呼び出しても、ディレクトリは変更されませんでした)。
これを機能させるにはどうすればよいですか?
スクリプトにCR(^ M)文字が含まれています。 Unixの行末(LFのみ)に変換します。ポータブルな方法で:
tr -d '\r' < your_script > output_script
CR文字で何が起こったかについてのOlivier Dulacのコメントに基づくいくつかの説明:まず、シェル言語では、CR文字は特殊文字と見なされません。スペースと見なされず、無視されません。以下に^M
と表記します。
echo $HOME^M
行には、$HOME
の後に^M
が続き、その後に新しい行が続く内容が出力されました。 CR文字を出力すると、カーソルは最初の列に置かれますが、直後に改行が続くため、目に見える影響はありませんでした。
cd $HOME^M
行では、$HOME
とCR文字の間にスペースがないため、どちらも同じ引数$HOME^M
にあり、このディレクトリは存在しません。エラーメッセージでは、$HOME
の後のCR文字が出力され、カーソルが最初の列に置かれたため、行の先頭がメッセージの残りの部分で上書きされていました: ":そのようなファイルまたはディレクトリーは「bashを使用した(最初の例)、ダッシュを使用した何も(2番目の例sh script.sh
、#!/bin/bash
はsh
でスクリプトを実行するように明示的に要求したため無視されました。あなたの場合はダッシュにする)。エラーメッセージは完全にシェルに依存しています。たとえば、zshはCR文字が印刷できないことを検出し、次のようなメッセージを出力します。
cd:そのようなファイルやディレクトリはありません:/ usr/local/src/^ M
(CR文字ではなく、文字「^」と「M」を使用)。これにより、問題の原因をはるかに簡単に検出できます。そうでない場合は、Olivierによって提案されているcat -ve
などの特殊文字を表示できるユーティリティ、またはストリームのバイトシーケンスを提供するhd
にstderrをリダイレクト/パイプする必要があります。
set -x
を使用すると、ファイルのソースが失敗する理由がわかります。
$ . test.sh
+ . test.sh
++ echo $'/home/braiam\r'
/home/braiam
++ cd $'/home/braiam\r'
: No such file or directory
++ cd $'/\r'
: No such file or directory
++ cd $'/usr/local/src/\r'
: No such file or directory
Vinc17が言ったように、スクリプトの\r
の部分を削除するだけで大丈夫です。 his solution を使用するか、dos2unix script.sh
、またはsed -i 's/\r//' script.sh
を使用できます。
以下のコマンドを使用して、CR文字を削除することもできます。
Perl -p -i -e "s/\r//g" script.sh
vi/vimを使用している場合は、
:set ff=unix
これと同じ問題があり、EOL文字をUNIX形式に変換することで修正しました。簡単な方法は次のとおりです。
すでにUNIX形式の場合は、別の形式(Windows)を選択してからUNIXに戻る