bash で値を含む文字列をコマンドとして実行するにはどうすればよいですか?

bash で値を含む文字列をコマンドとして実行するにはどうすればよいですか?

ここに私の小さな bash スクリプト スニペットを示します。

i=5
command='echo $i'
$command

このスクリプトを印刷したいのです5が、つまり echo を実行して 5 を印刷したいのですが、代わりに が印刷され続けます$i。どうすればこの問題を解決できますか?

答え1

それは次のようになります:

eval "$command"

の内容を$commandシェルコードとして評価したい場合。

$commandが で始まらないことを保証できない場合-(eval一部のシェルではbashオプションとして扱われる可能性があるため)、次を実行する必要があります。

eval " $command"

代わりに、 を使用します。 先頭の余分なスペースは、コマンドの解析方法には影響せず、で始まる場合$commandに のオプションとして扱われることを防ぎます。は、一部のシェル ( を含む) でも機能しますが、POSIX ではないため (IIRC)、や Bourne シェルなどでは機能しません。eval-eval -- "$command"bashdash

おそらく次の点に注意してください$command:

command='echo "$i"'

$isplit+globの対象となることを意図していない限り

コードを「変数」に保存するより良い方法は、関数を使用することです。

mycommand() { echo "$i"; }

(mycommandの代わりにを使用しますcommand。 はcommand既に存在するコマンドです)。

が/ /$commandの場合、動作はシェルによって異なります。breakcontinuereturn

もしあなた$command簡単なコマンドこれは単語のリストであり、その最初の単語が、単語のリストを引数として実行するコマンドとして検索されます。配列変数を使用します。

command=('echo' '$i' "$i")
"${command[@]}"

echoこれは、echo$iおよび の内容を引数として を実行します$i

command='echo $i ;x /* '$i
$command

(デフォルト値は$IFS)は、最も意味をなさないものです。 には$command文字列が含まれます。最初の文字列は$iそのまま残され、2番目の文字列は(一重引用符の外側にあるため)展開され、その後、その文字列は(二重引用符の内側にないため)分割+グロブの対象となり$command、その結果、いくつかの単語が、簡単なコマンドまた。

関連情報