一致する「」を探しているときに予期しないEOF-bashスクリプト


38

私はbashスクリプトを書いただけで、常にこのEOFエラーを受け取りました。

だからここに私のスクリプトがあります(OS Xでのみ動作します):

#!/bin/bash

#DEFINITIONS BEGIN
en_sq() {
    echo -e "Enabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart quotes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sq() {
    echo -e "Disabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart quotes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
en_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart dashes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart dashes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
#DEFINITIONS END
#---------------

#BEGIN OF CODE with properties
#This is only terminated if the user entered properties (eg ./sqd.sh 1 1)
if [ "$1" = "1" ]
    then
        en_sq
    elif [ "$1" = "0" ]
        then
            di_sq
fi

if [ "$2" = "1" ]
    then
        en_sd
        #exit 0 if both, $1 and $2 are correct entered and processed.
        exit 0
    elif [ "$1" = "0" ]
        then
            di_sd
            #exit 0 if both, $1 and $2 are correct entered and processed.
            exit 0
fi
#END OF CODE with properties
#---------------------------


#BEGIN OF CODE without properties
#This is terminated if the user didn't enter two properties
echo -e "\n\n\n\n\nINFO: You can use this command as following: $0 x y, while x and y can be either 0 for false or 1 for true."
echo -e "x is for the smart quotes, y for the smart dashes."
sleep 1
echo -e " \n Reading preferences...\n"
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart quotes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart quotes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X""
fi

status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart dashes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart dashes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X!"
fi

sleep 3
echo -e "\n\n You can now enable or disable smart quotes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sq" = "e" ]
    then
        en_sq
    elif [ "$sq" = "d" ]
        then
            di_sq
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done
SUCCESS="FALSE"

echo -e "\n\n You can now enable or disable smart dashes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sd" = "e" ]
    then
        en_sd
    elif [ "$sd" = "d" ]
        then
            di_sd
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done

そして、ここに私のエラーがあります:

./coding.sh: line 144: unexpected EOF while looking for matching `"'
./coding.sh: line 147: syntax error: unexpected end of file

回答:


31

質問を見るだけで問題を確認できます。行95の後に構文の強調表示が台無しになることに注意してください。

echo -e "Sorry, an error occurred. You have to run this on OS X""

エラーメッセージが示すように、一致しないがあり"ます。"上記の行から余分なものを削除するだけで大丈夫です。

echo -e "Sorry, an error occurred. You have to run this on OS X"

1
奇妙なことに、私は同じ問題を抱えていましたsudo echo ""。それは、ラインがあったからです。2つの二重引用符を削除して、sudo echo完全に機能させます。
ヴィンジー

@vinzeeなんでecho一緒に走るのsudo?とはいえ、あなたが説明することはあまり意味がなく、何か他のことが起こっていたに違いありません。
テルドン

sudo echoスクリプトはsudoコマンドの後半で必要になるので、私はそうしますが、ユーザーがパスワードを数分早く入力しなくて済むように、ユーザーに早くパスワードを入力してもらいたいのです。バグについては、ここで見たのと同じエラーがありましたが、2つの二重引用符を削除することで解決しました。他に何も起こりません
でした.-ヴィンジー

1
@vinzeeを読みたいかもしれませんスクリプト内で「sudo」コマンドを実行するにはどうすればよいですか?。引用に関しては、何か他のものがあったに違いありません。たとえば、引用符の後に削除された非印刷文字が含まれている場合があります。それとも、2つの単一引用符を持っていたし、その後、二重(echo ''")またはそのような何かが、があるように持っていた何かので、echo ""細かいです。
テルドン

リンクをありがとう、あなたは正しい。実行sudo echoは少し奇妙に感じました。そして、今夜、Linuxのインストールを再試行し、結果をここにコメントして戻ります。
ヴィンジー

3

このエラーは、実際の状況では追跡が難しい場合があります。ここで、現実世界の状況に対する1つのソリューションを提供します。スクリプトを例として使用します。

シェルスクリプトを更新しました。実行すると、次のエラーメッセージが表示されました。

/somepath/bin/myshellscript: line 1508: unexpected EOF while looking for matching `"'
/somepath/bin/myshellscript: line 1520: syntax error: unexpected end of file

line 1508 elif [ "$project" ]; then

これは、二重引用符のペアがある最後の行です。

通常、シェルスクリプトを変更するたびにチェックします。今回、私は1日待って、どこで修正を加えたか忘れました。問題は、この行の前のどこでも発生しました(1508)。問題は、1508行目をコメントアウトしたことです。

#elif [ "$project" ]; then

シェルの実行者は、1508行にまだ問題があると述べています。

次に、元のシェルスクリプトのコピーを作成しました。下部から大量のコードを削除します。次に、次のコマンドでコードを検証します

bash -n mysbashscript

mybashscript: line 515: unexpected EOF while looking for matching `"'
mybashscript: line 561: syntax error: unexpected end of file

現在、私のファイルは元のサイズの1/3です。私はすぐに問題を見ました:

497 prepare_alignment() {
498     local projdir=${1:?"did not give project directory"}
499     local samp=${2:?"did not give sample name"}
500     local merged=${3:?"must give merged bam file name} # here is the problem

一部の理由では、{}内の一致しない "は、シェルパーサーによってキャプチャされません。これは、シェルパーサーをさらに改善できる場所です。

問題を見つけるための最速のアルゴリズムは、コードの半分を下から削除することです。構文エラーがなくなると、この半分になります。構文エラーがまだ存在する場合、問題は上半分にあります。

後半に問題がある場合は、削除を元に戻します。このプロセスを繰り返します。問題の原因を見つけるために、より小さいサイズに絞り込むことができます。

コードを削除するときは、コードのセクション全体を削除する必要があります。たとえば、関数全体。

bash -n scriptnameを使用するか、単にスクリプトを直接実行できます。両方とも機能するはずです。


1
「いくつかの理由で、比類のない」内部は{}シェルパーサによって捕獲されていません。」構文的に、それが理由だけということですされた?すなわちライン500で開かれた文字列は、行1508に閉じ、その後、別されたライン1508上で、マッチ文字列は、閉じ取得決してその1508年に開かれます。
philh

bashの引用動作については調査しませんでした。Bashには複数行の引用符 "line1 \ nline2"が含まれている可能性があります。シェルでは、<< ENDMARKを使用して複数行の引用符を実行します。おそらく、二重引用符を直接使用して複数行を引用できるようになりました。この機能により、デバッグが非常に難しくなります。
ケミンジョウ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.