次のエラーが発生します。
/tmp/filechecking.sh: line 11: warning: here-document at line 6 delimited by end-of-file (wanted `EOF')
/tmp/filechecking.sh: command substitution: line 8: unexpected EOF while looking for matching `"'
/tmp/filechecking.sh: command substitution: line 11: syntax error: unexpected end of file
/tmp/filechecking.sh: line 6: bad substitution: no closing "`" in `
echo "${filetype[@]}"
done
私のスクリプトは
losystem=`ls /appl/vortex/archive/cons/*`
echo "${losystem[@]"
for indsystm in "${losystem[@]}"
do
filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select file_type from expected_file where starters_package_version = '4.0' and system_id = 'DAL'
go
EOF`
echo "${filetype[@]}"
done
誰でもここで構文エラーが何であるかを助けることができますか?
答え1
losystem=`ls /appl/vortex/archive/cons/*` echo "${losystem[@]" for indsystm in "${losystem[@]}" do filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF select file_type from expected_file where starters_package_version = '4.0' and system_id = 'DAL' go EOF` echo "${filetype[@]}" done
EOF
構文エラー自体は、次の行に表示されるバックティックによって引き起こされます。コサロナンダの答え。しかし、スクリプトに他の問題があります。したがって、シェルスクリプト技術をより良くするために、より詳細に見てみましょう。
最初の誤解:あなたが言ったように"${losystem[@]}"
、あなたは配列を作成しました。。あなたは..しませんでした。これを行うには、変数の割り当てに括弧を使用する必要があります。
同様に、する配列を使用すると、使用する必要はありませんls
。球は配列の要素に直接拡張されます。
ls
とにかく出力を解析しないでください。これは幸運です。
したがって、変数を設定する正しい方法losystem
は大量にその要素はその中にあるファイルとディレクトリです/appl/vortex/archive/cons/
。
losystem=(/appl/vortex/archive/cons/*)
2行目のコマンドecho
に終端がありません}
。
また、printf
ここで使用することもできます。
printf '%s\n' "${losystem[@]}"
また見なさい:
ループfor
はBash配列の要素を繰り返すのに適しているlosystem
ため、上記の修正を適用した場合は変更せずに使用できます。
しかし、あなたはそうではありませんでした。必要アレイなどを設定してください。詩(よりきれいで直感的な)forループで直接ファイルglobを宣言します。
for indsystem in /appl/vortex/archive/cons/*; do
これはまた、Bash配列に依存しないという点でPOSIXと互換性があるという利点があるため、より広い範囲のシェルで動作します(つまり、移植性が高い)。
スクリプトの次の部分はfiletype
設定しているように見えるため、確認するのは難しいです。出力命令しましたが、isql
あなたはしませんでした。する印刷を除くこの出力のすべて(誤った形式)echo
。 (もう一度見てください。なぜprintfがechoより優れているのですか?)
最も明白な方法は、変数をまったく設定せずにコマンドを直接実行することです。これにより、実際に必要に応じて独自の出力が印刷されます。
isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select file_type from expected_file where starters_package_version = '4.0' and system_id = 'DAL'
go
EOF
気づく私はそれに慣れていないので、isql
このコマンドの正確性を証明しません。 これは自分で書いたコマンドであり、変更はありません。正確であってもなくてもよい。
しかし、このスクリプトの最も奇妙なことは、配列indsystem
のすべての要素を設定またはlosystem
そうしようとしていることです。あなたは価値を引用しません"$indsystem"
。
これは「部屋の中の象」です。私はあなたの心を読むことができないので、このロジックを修正することはできません。何をしたいのかは全くわかりません。
いくつかの異なる可能性を考えることができます。
isql
たぶん、ディレクトリ内のすべてのファイルに対してコマンドを実行したいと思うかもしれませんcons
。 (この場合、isql
コマンドはどこかにある変数を参照し、indsystem
ディレクトリで実行されていないことを確認する必要があります。)- ディレクトリが空でない
isql
場合にのみ、コマンドを一度だけ実行したい場合があります。cons
isql
引用符なしでコマンドを実行したい場合がありますがindsystem
、ディレクトリ内のファイル/ディレクトリと同じ方法で複数回実行してくださいcons
。 (これは私が修正したコードバージョンで行うことですが、あまり意味がありません。)
これらの可能性のどれも確かに正確ではないので、スクリプトが実際に何をしようとしているのかわかりません。
それでも、これがシェルスクリプトについてもっと学ぶのに役立つことを願っています。 Bashスクリプトを正しく学ぶには、次のことをお勧めします。ウルウィッチカーニバルガイド。
私はまた、私の専門的な経験を通して、このスクリプトと同じくらい多くの問題があるシェルスクリプトには、一般的にアーキテクチャ/デザインの問題があることを発見したと言いたいと思います。より高いレベルで、その後通常真に実行可能なソリューションに到達する前に、スクリプトが必要な理由を徹底的に確認する必要があります。
答え2
この文書の閉じ区切り記号は、1行に単独で表示する必要があります。
filetype=`isql -UDAS -PCDRD -SYTRT_DCS_FRET << EOF
select file_type from expected_file where starters_package_version = '4.0' and system_id = 'DAL'
go
EOF
`
$(...)
通常、新しいコードではバックティックの代わりにバックティックを使用することをお勧めします。$(...)
ネスト機能が良く、一般的にビューにも良いからです。
filetype=$( isql -UDAS -PCDRD -SYTRT_DCS_FRET <<EOF
select file_type
from expected_file
where starters_package_version = '4.0'
and system_id = 'DAL'
go
EOF
)
$(...)
使用する方が良い理由の詳細は、「* shシェルではバックティック(「cmd」など)は使用されなくなりましたか?」