コマンドを変数として保存し、bashでランダムに実行する方法は?

コマンドを変数として保存し、bashでランダムに実行する方法は?

コマンドを変数として保存し、bashでランダムに実行する方法は?

command1="
   convert -size 2000x1000 xc:none -gravity center \
    -stroke yellow -pointsize 50 -font Courier-BoldOblique -strokewidth 3 -annotate +100+100 "${caption}" \
    -blur 0x25 -level 0%,50% \
    -fill white -stroke none -annotate +100+100 "${caption}" \
    in.jpeg  +swap -gravity center -geometry +0-3 \
    -composite  out.jpeg
"
command2="
   convert -size 2000x1000 xc:none -gravity center \
    -fill white -pointsize 50 -stroke none -annotate +100+100 "${caption}" -channel alpha -evaluate multiply 0.35 -trim +repage \
    in.jpeg  +swap -gravity center -geometry +0-3 \
    -composite  out.jpeg
"

私は何を試しましたか?

COMMANDS=("command1" "command2")
$(eval $(shuf -n1 -e "${COMMANDS[@]}"))

必要な出力は、2つの変換コマンドのいずれかをランダムに実行することです。必要な結果を得るにはどうすればいいですか?何が間違っていますか?

以下からヒントを得ました。

ランダムコマンドの実行

シェルスクリプトの変数にコマンドを保存する方法

助けてくれてありがとう!

答え1

機能を使用してください。

command1(){ 
   convert -size 2000x1000 xc:none -gravity center \
    -stroke yellow -pointsize 50 -font Courier-BoldOblique -strokewidth 3 -annotate +100+100 "${caption}" \
    -blur 0x25 -level 0%,50% \
    -fill white -stroke none -annotate +100+100 "${caption}" \
    in.jpeg  +swap -gravity center -geometry +0-3 \
    -composite  out.jpeg
}

command2() {
   convert -size 2000x1000 xc:none -gravity center \
    -fill white -pointsize 50 -stroke none -annotate +100+100 "${caption}" -channel alpha -evaluate multiply 0.35 -trim +repage \
    in.jpeg  +swap -gravity center -geometry +0-3 \
    -composite  out.jpeg
}

理由を調べるコマンドを実行しようとすると変数が失敗する理由

答え2

まず、引数にスペースやリテラルグローバル文字がある場合は機能しません。

command1="convert ... -fill white -stroke none -annotate +100+100 "${caption}" ...

構文強調表示もその${caption}部分いいえリーダー。引用符は引用符内には影響しません。つまり、パラメータで拡張された引用符はリテラルなので、再引用しません。

望むより:

2つのより良いオプションは、コマンドを別々の関数または別々の配列に保存することです。残念ながら、名前を指定する必要があり(番号付き)、関数の配列または配列の配列を持つことはできません。

cmd1次に、andという名前の関数または配列があるとし、そこで行ったように1つを選択し、関数を使用しているcmd2場合は実行します。

commands=(cmd1 cmd2)
chosen=$(shuf -n1 -e "${commands[@]}")
"$chosen" args...

または、配列を使用している場合は、名前参照を使用して配列にアクセスする必要があります。

commands=(cmd1 cmd2)
declare -n chosen=$(shuf -n1 -e "${commands[@]}")
"${chosen[@]}" args...

関連情報