web-dev-qa-db-ja.com

パラメータを拡張するためのBashスクリプトループ

whiptail を使用して、別のプログラムからの出力に基づいてチェックボックスリストを生成したいと思います。最初のプログラムからの出力の各行の最初のWordのみが必要なので、awkを使用して抽出します。

Bashが配列を処理する方法について学ぶために、 私はtldpによってこのリンクを使用していますここ から配列のサイズを確認する方法を取得しました。

これは期待どおりに実行されませんが、echo出力をコピーし、その前に「whiptail」と入力すると、機能します。

このコードを修正して機能させるにはどうすればよいですか?

program.sh :

#! /bin/bash
find ./  -printf "%f\n"

mainscript.sh :

#! /bin/bash
MYARRAY=($(./program.sh -l | awk '{print $1;}'))
MYPARAMS=" --checklist \"\" 15 40 5"
i=0
while [[ $i -lt ${#MYARRAY[@]} ]]
do
        MYPARAMS+=" \"${MYARRAY[$i]}\" \" \" off"
        i=$[$i+1]
done
whiptail $MYPARAMS
echo $MYPARAMS
exit
1
USERID_UNK

なぜMYPARAMSを配列ではなく文字列にしたのですか? MYPARAMS--checklist "" 15 40 5 "foo1" " " offのような文字列であるため、シェルコマンドラインwhiptail $MYPARAMSは、引数--checklist""を指定してwhiptailが呼び出されます。 (2つの二重引用符で構成される文字列)、15405"foo1"""、およびoff。変数展開を引用符で囲まないままにすると、その値は各空白シーケンスでフィールドに分割され、結果のフィールドはワイルドカードパターンとして扱われ、いずれかのファイルと一致すると展開されます。引用符はシェル構文に属し、変数展開の一部としてではなく、シェルパーサーによってのみ展開されます。

evalが組み込まれているシェルパーサーを呼び出すことはできますが、引用を正しく行うことは困難です。アイテムにシェル構文でそれ自体を表さない文字が含まれている可能性がある場合は、特に困難です。

配列は、文字列のリストを格納する正しい方法です。使用するタグのリストにMYARRAYが正常に設定されていると仮定すると、その配列をループしてパラメーター配列を作成できます。

MYPARAMS=()
for t in "${MYARRAY[@]}"; do
  MYPARAMS+=("$t" " " "off")
done
whiptail "${MYPARAMS[@]}"

あまり望ましい解決策ではありませんが、evalを使用できます。

eval whiptail $MYPARAMS

問題は引用だと思います。ただし、MYPARAMSを配列として作成することはでき、期待どおりに機能します。

#! /bin/bash
MYARRAY=($(./program.sh -l | awk '{print $1;}'))
MYPARAMS=( --checklist "" 15 40 5 )
i=0
while [[ $i -lt ${#MYARRAY[@]} ]]
do
        MYPARAMS+=( "${MYARRAY[$i]}" " " off )
        i=$[$i+1]
done
whiptail "${MYPARAMS[@]}"
echo "${MYPARAMS[@]}"
exit
1
outlyer