シェルスクリプトには興味深いバグがあります

シェルスクリプトには興味深いバグがあります

私はbashGNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)とDebianの最新のダッシュアクション(ダッシュバージョンを取得する方法?)でこの動作を見つけました。

エラーは次のとおりです。

/bin/echo "Silent Err 'unexpected EOF while looking for matching' Example:"

if [ 0 -eq 1 ]; then
        /bin/echo "HERE IS MISTAKE WITHOUT QUOTE IN THE END
        exit
fi

/bin/echo " BLACK HOLE "
/bin/echo " CODE WILL NEVER PROCEED "

if [ 0 -eq 1 ]; then
        /bin/echo "SECOND MISTAKE
        exit
fi
/bin/echo "normal code... will work";
/bin/echo "Good and silent exit without any notice about BLACK HOLE code..."
/bin/echo "exit."

放射:

# bash bug_as_is.sh 
Silent Err 'unexpected EOF while looking for matching' Example:
normal code... will work
Good and silent exit without any notice about BLACK HOLE code place...
exit.

if then fiエラーは、最初のブロックが参照されたときにのみ発生します。

# bash unbug.sh 
Silent Err 'unexpected EOF while looking for matching' Example:
 BLACK HOLE 
 CODE WILL NEVER PROCEED 
unbug.sh: line 20: unexpected EOF while looking for matching `"'
unbug.sh: line 24: syntax error: unexpected end of file

これはよく知られているエラーですか、それとも私が本物のダイヤモンドを見つけましたか? (;;

この行動の根拠は何ですか?

答え1

Bashにエラーがありません。コードが正常に動作します。

echobashは、文字列が奇妙に見え、bashコードを含む場合でも、複数行の文字列を引数として受け入れます。

以下は、echo複数行の文字列出力を含むステートメントです。

        /bin/echo "HERE IS MISTAKE WITHOUT QUOTE IN THE END
        exit
fi

/bin/echo " BLACK HOLE "
/bin/echo " CODE WILL NEVER PROCEED "

if [ 0 -eq 1 ]; then
        /bin/echo "SECOND MISTAKE

これを明確にするために長い文字列を"multiline string omitted"。まあ、コードは簡単です:

/bin/echo "Silent Err 'unexpected EOF while looking for matching' Example:"

if [ 0 -eq 1 ]; then
        /bin/echo "multiline string omitted"
        exit
fi
/bin/echo "normal code... will work";
/bin/echo "Good and silent exit without any notice about BLACK HOLE code..."
/bin/echo "exit."

上記のコードは正常に動作するコードです。

答え2

「この行動の中枢」が何を意味するのかはよくわかりませんが、解釈すると次のようになります。

(一見すると)一致しない引用文字列は"HERE IS MISTAKE WITHOUT QUOTE IN THE END実際には引用文字列リテラルの始まりです。文字列リテラルは最初の文字を超えて拡張され、先頭の二fi重引用符文字までのすべての内容が含まれます"SECOND MISTAKE

したがってbash、人間の観点からは不正確であっても全体的な混乱を分析することができます。 1は数値的に0に等しくないため、次のコード/bin/echo "HERE IS MISTAKEのブロック全体は実行されません。したがって、(明らかな)文字列は可能なコマンドで正しく解析されますが、実行しようとしないため、バグやその他のエラーは表示されません。fi"SECOND MISTAKESECOND MISTAKEbashSECOND: command not found

要約すると、両方の行に引用符がない場合、bashコードはSingleの「true」句に解析されますが、if-then-fi条件は偽であるため、bash人間の目でエラーと見なすことができるコマンドを実行しようとしないでください。関連する構文エラーは発生しません。

関連情報