シェルスクリプトでバグを追跡中に、このコードスニペットで次の動作が見つかりました。
declare -a filelist
readarray filelist < <(ls -A)
readonly filelist
for file in "${filelist[@]}"; do
sha256sum ${filelist[$file]} | head -c 64
done
配列がfilelist
二重引用符で囲まれていない場合、コマンドは成功します。私はコーディングを改善するためにShellCheckを使用しており、次の提案を受けました。
二重引用符はワイルドカードとワードセパレータを防ぎます。
この場合、単語の分割について心配することはありませんが、他の多くの場合は心配するので、コードの一貫性を維持しようとします。ただし、配列を二重引用符で囲むと、コマンドは失敗します。コードを単一の要素に減らすと、次のような結果が表示されます。
bash-5.0# sha256sum ${filelist[0]} | head -c 64
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
bash-5.0# sha256sum "${filelist[0]}" | head -c 64
sha256sum: can't open 'file1
': No such file or directory
明らかに...二重引用符は使用できません。この場合、単語の分離は問題にならないからです。しかし、これからもそうかもしれないので、投稿をしたいと思いました。
私の質問は2つの部分で構成されています。
- 上記の二重引用符の配列に加えて、単語の分割を防ぐための「ベストプラクティス」方法はありますか?
配列の一重引用符はどこから来たのですか?編集:一重引用符はありません。一重引用符は、開けられないファイル名を表示するエラーです。
また、疑問に思われecho ${filelist[0]}
ない追加の改行文字が含まれるのはなぜですかecho "${filelist[0]}"
?
ベストアンサー1
参照配列の拡張にはまったく問題はありません。
もちろん、結果を知って受け入れるならば、引用しなくても大丈夫です。引用符のない拡張子は、分割とワイルドカードの影響を受けます。そして、コードから${filelist[…]}
IFS文字を削除(文字列に<space>
、<tab>
またはが含まれている場合は分割<newline>
)を実行する必要があります。
これは引用されていない拡張が実行する作業であり、末尾<newline>
。
何作る問題は、使用するときにreadarray
各配列要素から末尾の区切り文字を削除しないことです。これにより、エラーメッセージに反映された末尾が保持されます
。<newline>
使用できるものは次のとおりです。
readarray -t filelist < <(ls -A)
この-t
オプションは、各ファイル名から末尾の改行をすべて削除します。
-t 読み取った各行から末尾の区切り文字(デフォルトの改行)を削除します。
しかし、コードには他の問題があります。
配列を宣言または消去する必要はありません
filelist
。これはデフォルトでreadarrayによって行われます。これは他の状況でも必要です。解析された出力は必要ありません
ls
。実際、これは悪い考えです。配列のファイルのリストを取得する最も簡単な方法は次のとおりです。filelist=( ./* )
そして、より良い結果を得るためにディレクトリを使用しないことをお勧めします。
for file in ./*; do [[ -f $file ]] && filelist+=( "$file" ) done
ループ内では
$file
var値を使用する必要があります。for file in "${filelist[@]}"; do sha256sum "$file" | head -c 64 done
for file in "${!filelist[@]}"; do
リストを使用しない限り鍵ソート。リスト全体を処理するだけです。一つsha256sumに電話してください。
sha256sum "${filelist[@]}" | cut -c -64
改善されたスクリプトは次のとおりです。
filelist=() # declare filelist as an array and empty it.
for file in ./*; do
if [[ -f $file ]]; then
filelist+=( "$file" )
fi
done
declare -r filelist # declare filelist as readonly.
sha256sum "${filelist[@]}" | cut -c -64