現在、700行を超えるbashスクリプトがあります。特に長い編集作業を終えた後、次のエラーが発生します。
./run_me.sh: line 693: unexpected EOF while looking for matching `''
./run_me.sh: line 702: syntax error: unexpected end of file
しかし、693行には何の問題もありません。上記の引用はありません。
私はrunningを試しましたが、bash -x run_me.sh
最後の行が実行されていることがわかりますが、その行には問題ありません(そしてその行と693の間のコードは実際にはほとんどのコードです)。
コード全体をコメントアウトできますが、そうすると、EOFエラーではなく、関数の欠落などによるエラーが発生する可能性が高くなります。
もしそうなら、行番号が誤って報告された場合、欠落している引用符をどのように見つけることができますか?
(Bashの行番号がなぜそんなに離れているのですか?)
編集する
ところで、私は(ストリップにコメントを付けて)私の特定のエラーを見つけました。このエラーは、}
エラーメッセージが示す行の近くにまったくない任意の行番号の変数の拡張によって実際に失われました。ここでは、引用ベースの構文の強調表示は役に立ちません。たとえば、"${MY_ARRAY[@]"
(必要がある)に欠けている中括弧があります"${MY_ARRAY[@]}"
。
答え1
ローテックアプローチは
tr -cd "'\n" < run_me.sh | awk 'length%2==1 {print NR, $0}'
tr
一重引用符と改行文字を除くすべての文字を削除し、awk
奇数文字(一致しない引用符など)を含む行を識別します。個別に確認してください。有効な文字列が表示され"That's not a bug!"
ます。
問題が強調表示されない場合は、tr -cd '"\n'
(一致しない二重引用符を検索)を使用してもう一度やり直してください。 次に、tr
Allow()
と[]
Final {}
Pass を展開します。この時点で、出力を手動でチェックすることはあまり効率的ではありません。一方(
、通常は同じ行で一致しますが、引用符と角かっこはほとんど常に一致しますが、 )
そうではありません。 (ただし、不一致が見つかると、代わりに入力するOPの実際の問題が明らかになります。){
}
{
}
"${MY_ARRAY[@]"
"${MY_ARRAY[@]}"
問題の範囲を中括弧の不一致に絞り込んだ場合、特にファイル内の範囲を絞り込んだ場合は、計画Bに進みます。vim
(または)でvi
ファイルを開きます。{
エラーが発生したと思う前に、その文字に移動してを入力してください%
。カーソルが開始した位置と一致すると}
思われる位置に移動したら、{
次の位置に移動して{
繰り返します。開始位置}
と一致しない位置にジャンプすると、2つの中{
括弧の間にエラーが発生します。移動しない場合は、現在の場所とファイルの終わりの間にエラーが発生しました。大きくする。
このアプローチは、C、C ++、Java(コンパイラが不十分な場合)などの言語のプログラムファイルには少し適していますが、シェルスクリプトではかなりうまく機能します。
答え2
次の外部リンティングツール住宅検査問題を検出し、それbash
自体よりも良いメッセージと場所を持つことができます。
echo
ほとんどが中間のステートメントであるプログラムの場合、ShellCheckは引用符付き文字列を解析できないことを伝えます。"${MY_ARRAY[1]"
キャラクターの問題を非難し、$
パラメータ拡張に問題があることを示唆した。
ShellCheckはVim、Emacs、SublimeText、Atomと連携します。
答え3
最も簡単な方法は?使用しているシェルを認識する構文の色付け機能を備えたエディタを使用し、目視検査を実行します。文字列の色が見える場合は、引用符がありません。ほぼすべてのまともなプログラミングエディタには構文の色付けがあります。
構文の色付けは時々間違っている可能性がありますが、これは通常、プログラムが複雑すぎて人にも間違いを犯す可能性があるという信号です。
"
シェルプログラミングの場合は、where と を区別'
しやすいフォントを使用してください。`
誤ってASCII引用符のように見える非ASCII文字を使用したことを確認してください‘’“”
。
答え4
私はG-Manの低級技術ソリューションを使用して、2000を超えるラインbashスクリプトで大きな問題を解決しました。
G-Manの答えが一重引用符であるように、奇数個の二重引用符に対して同じことを行う次の行を追加しました。
tr -cd "\"\n" < my_script.sh | awk 'length%2==1 {print NR, $0}'
ちなみに、shellcheck.netはとても素晴らしく、すべての良いスクリプトはそれを経なければなりません。