複数のパラメータを使用して別のスクリプトを実行するスクリプトを作成したいと思います。
exp=([1]=bloc [2]=ins [3]=rep [4]=op)
for j in ${!exp[*]}
do
arr=([1]=mem [2]=gen [3]=usr)
for i in ${!arr[*]}
do
var="bash createGnuploat.sh "${exp[j]}" ../Result/ 0" ${arr[i]} ${exp[j]}
$var
done
done
このエラーがあります。
run.sh: line 9: =bash createGnuploat.sh op ../Result/ 0: Aucun fichier ou dossier de ce type
何の問題がありますか?
答え1
この行には、いくつかの構文と引用の問題があります。
$var="bash createGnuploat.sh "${exp[j]}" ../Result/ 0" ${arr[i]} ${exp[j]}
あなたの質問のためのよりクリーンなバージョンのスクリプトは次のとおりです。
for j in bloc ins rep op; do
for i in mem gen usr; do
bash createGnuploat.sh "$j" ../Result/ 0 "$i" "$j"
done
done
このような議論の目的が何であるかは分からないので、直接確認してみなければならcreateGnuploat.sh
ないだろう。
答え2
コマンドを変数に保存する必要がある場合は、文字列を使用しないでください。文字列は機能しません。バラよりバッシュFAQ #50。関数または配列を使用してください。
var="bash createGnuploat.sh "${exp[j]}" ../Result/ 0"
あなたの行は、2つの単語${arr[i]}
(コマンド名として扱われます)と${exp[j]}
(コマンドの最初で唯一の引数になります)が続く割り当てとして解析されます。質問またはエディタで構文の強調表示を確認すると、引用符付き文字列内に何があるかが表示されます。
変数の置換には常に二重引用符を使用してください"$foo"
。たとえば、そうでない場合、変数の値はグローバルパターンとして解釈される単語に分割されます。 (0.01%の場合、これは望ましい動作です。二重引用符を省略してください。)配列の場合、使用は配列"${foo[@]}"
の各要素を別々の単語に入れます("${foo[*]}"
単語の場合、配列の要素はスペースで区切ります。引用符で囲まれ、各要素は別々の単語で区切られ、グローバルパターンとして解釈されます。
以下は、関数を使用して書き換えられたコードの断片です。
create_plot () {
bash createGnuploat.sh "${exp[$2]}" ../Result/ 0 "${arr[$1]}" "${exp[$2]}"
}
for j in "${!exp[@]}"
do
arr=([1]=mem [2]=gen [3]=usr)
for i in "${!arr[@]}"
do
create_plot "$i" "$j"
done
done
関数の代わりに配列変数を使用する方がより適切な場合:
for j in "${!exp[@]}"
do
arr=([1]=mem [2]=gen [3]=usr)
for i in "${!arr[@]}"
do
var=(bash createGnuploat.sh "${exp[j]}" ../Result/ 0 "${arr[i]}" "${exp[j]}")
"${var[@]}"
done
done