Bash構文エラー:予期しないファイルの終わり


98

これは、Bashの非常に単純なスクリプトです。これがコードです:

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

sh file.shを実行した後:

構文エラー:予期しないファイルの終わり

回答:


137

file.shにはCRLF行終端記号が付いていると思います。

走る

dos2unix file.sh

その後、問題は修正されます。

あなたはこれでubuntuにdos2unixをインストールすることができます:

sudo apt-get install dos2unix

この問題の背後にある理由は何ですか?私は通常Windowsで作業しますが、UNIXシステムにスクリプトを転送する必要があります。
CMCDragonkai 2013年

Windowsの改行は「\ r \ n」ですが、Linuxでは「\ n」です。
clyfish 2013年

8
@KeesdeKooter何かがうまくいかなかったからといって、反対票を投じるべきだとは言えません。明らかに28の賛成票で有効でした。それは私にはうまくいかなかった単純なもので十分です。問題に対して複数のソリューションが存在する可能性があるため、SOが質問に対する複数の回答を許可したのはそのためです。
Jeff Wilbert、2015

2
notepad ++エディターを使用して、[編集]> [EOL変換]> [古いMac形式]で解決しました。
raktale 2016年

Notepad ++でbashファイルを編集できる場合。「編集」->「EOL変換」->「Macintosh(CR)」に移動します。Windows OSをお使いの場合でも、Macintosh(CR)に変更してください。
2017

126

チェックする別のこと(ちょうど私に起こりました):

  • 単一行関数の本体をセミコロンで終了する

つまり、この無害に見えるスニペットでも同じエラーが発生します。

die () { test -n "$@" && echo "$@"; exit 1 }

ダムパーサーをハッピーにするには:

die () { test -n "$@" && echo "$@"; exit 1; }

3
+1次のような角かっこを含むコードスニペットにも適用されます:[["$#" == 1]] && [["$ arg" == [1,2,3,4]]] && printf "%s \ n ""何とか "|| {printf "%s \ n" "何とか"; 使用法; } ............以前に定義された関数 'usage'を呼び出した直後の波括弧内のセミコロンに注意してください。これを忘れると、同じ構文エラーが発生します。予期しないeofです。
Cbhihe

あなたはそれを釘付けにしました。実際のところ、;Everyステートメントは末尾で終了する;ことが予想されているので簡単です。例:if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fiはそのエラーを生成しますが、最後にif [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash; fi;は小さなセミコロンに気づきません。つまり、:.bashfi
Emmanuel Mahuni

1
zshユーザーから共有されたスクリプトでこれを行いました。前者は動作しますzshが動作しませshbash。私が4人だったらいいので、これで4つの賛成票を出すことができます
Davos

40

また、if句で間違った構文を使用してこのエラーメッセージを取得しました

  • else if (構文エラー:予期しないファイルの終わり)
  • elif (正しい構文)

それが機能するまでコメントアウトしてデバッグしました


どうもありがとう..誰かがこの男にメダルをあげてください
ハッピーハッピー

16

クローズされていないif => fi句もこれを発生させます

ヒント:スクリプトが巨大な場合は、トラップを使用してデバッグしてください...

例えば

set -x
trap read debug

1
私はまさに「fi」を忘れました!ありがとう:)できれば、みんなの利益のために、トラップを使用するヒントを少し詳しく説明します。
Carles Alcolea

3
遅れてすみません、私の友人。「トラップ」コマンドは、すべての行の後に本質的に中断することによってスクリプトをデバッグする方法です。充実した議論はここにある:stackoverflow.com/questions/9080431/...
theRiley

1
とても役に立ちました。がヒットunexpected end of fileするとすぐにエラーが発生することに注意してくださいfi
ステファンB.

8

StackOverflowの同様の問題から私はこの答えを得ました

Vimでファイルを開いてみてください

:set fileformat=unix

行末をUNIXの末尾に変換し、問題が解決するかどうかを確認します。Vimで編集する場合は、:set fileformat = unixコマンドを入力してファイルを保存します。Notepad ++やAtomなど、他のいくつかのエディターには行末を変換する機能があります。

ありがとう@lemongrassnginger


これらはdos2unix、受け入れられた回答が助言するように実行する代替方法にすぎません。
ulidtko

7

cygwinで私は必要でした:-

 export SHELLOPTS
 set -o igncr

.bash_profile内。この方法では、unix2dosを実行する必要はありませんでした


6

だから私はこの投稿を見つけました、そして答えは私を助けませんでした、しかし私はそれがなぜ私にエラーを与えたのか理解することができました。持っていた

cat > temp.txt < EOF
some content
EOF

問題は、上記のコードを関数内にコピーして、誤ってコードをタブ化したことです。最後のEOFがタブ化されていないことを確認する必要があります。


1
これはまさに私のケースでした。私はEOF4つのスペースで字下げしており、bashはそれを解析しませんでした。スペースを削除すると問題が修正されました。
aexl 2016年

5

「if-fi」ステートメントを1行で記述したときに問題が発生しました。

if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi

マルチラインを書いて私の問題を解決しました:

if [ -f ~/.git-completion.bash ]; then 
    . ~/.git-completion.bash
 fi

3

これは、括弧を使用して関数を呼び出そうとしたときに発生していました。

run() {
  echo hello
}

run()

でなければなりません:

run() {
  echo hello
}

run

2

WINDOWSの場合:

私の場合、私はWindows OSで作業しており、autoconfの実行中に同じエラーが発生しました。

  • NOTEPAD ++ IDEでconfigure.acファイルを開くだけです。
  • 次に、EOL変換を含むファイルを次のようにWindows(CR LF)に変換しました。

    編集-> EOL変換-> WINDOWS(CR LF)


1

私はあなたのコードをファイルにカットアンドペーストすることができ、それは正しく実行されました。このように実行すると、うまくいくはずです。

あなたの「file.sh」:

#!/bin/bash
# june 2011

if [ $# -lt 3 -o $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

コマンド:

$ ./file.sh arg1 arg2 arg3

「file.sh」は実行可能でなければならないことに注意してください。

$ chmod +x file.sh

入力の方法(パイプ、ニンジンなど)のエラーb / cが発生している可能性があります。条件を2つに分割してみることもできます。

if [ $# -lt 3 ] || [ $# -gt 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

または、をbash使用しているため、組み込みの構文を使用できます。

if [[ $# -lt 3 || $# -gt 3 ]]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

そして最後に、もちろん、3つの引数が指定されているかどうかを確認することもできます(クリーンで、POSIXシェルの互換性を維持します)。

if [ $# -ne 3 ]; then
   echo "Error... Usage: $0 host database username"
   exit 0
fi

まだ同じエラーが発生します。

奇妙なことに、私はあなたのコードをカットアンドペーストし、それは期待通りに機能しました。エラー出力はもうありましたか?多くの場合、bashは行番号をリストします。また、どのシステムを実行していますか?(Linux、MacOS、BSD、ディストリビューションなど)
aaronstacy

0

私はあなたの例をファイルに切り貼りしました。bashの下では問題なく実行されました。何の問題もありません。

十分な対策として、bashは気にしないでくださいが、改行で終了するようにしたい場合があります。(これは、最終改行の有無に関係なく実行されます。)

誤って制御文字をファイルに埋め込んだ場合、奇妙なエラーが発生することがあります。短いスクリプトなので、質問からここにStackOverflowに貼り付けるか、単純に再入力して、新しいスクリプトを作成してみてください。

どのバージョンのbashを使用していますか?(bash --version

幸運を!


0

.shファイルが存在するディレクトリの名前にスペース文字が含まれていないことを確認してください。例:「新しいフォルダ」というフォルダにあるとしたら、引用したエラーに遭遇することになります。代わりに、「New_Folder」という名前を付けます。これがお役に立てば幸いです。


0

どうやら、シェルの一部のバージョンでは、スクリプトの最終行に改行がない場合にもこのメッセージが出力される可能性があります。


0

Ubuntuの場合:

$ gedit ~/.profile

その後、File -> Save asセットend lineUnix/Linux



0

MacOSを使用している場合:

Windows形式のファイルを受け取り、MacOSで実行したい場合にこのエラーを確認するには、次のコマンドを実行します。

brew install dos2unix
sh <file.sh>

0

関数定義の閉じ中かっこがないと、このエラーが発生します。

function whoIsAnIidiot() {
    echo "you are for forgetting the closing brace just below this line !"

もちろんこれはこのようにするべきです...

function whoIsAnIidiot() {
    echo "not you for sure"
}

0

私の場合、\次のような冗長性があります:

function foo() {
    python tools/run_net.py \
                           --cfg configs/Kinetics/X3D_8x8_R50.yaml \
                           NUM_GPUS 1 \
                           TRAIN.BATCH_SIZE 8 \
                           SOLVER.BASE_LR 0.0125 \
                           DATA.PATH_TO_DATA_DIR ./afs/kinetics400 \
                           DATA.PATH_PREFIX  ./afs/kinetics400  \  # Error
}

ありませ\の終わりにDATA.PATH_PREFIX ./afs/kinetics400

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.