これが私の小さなbashスクリプトスニペットです。
i=5
command='echo $i'
$command
このスクリプトで5
を出力して、エコーを実行して5を出力してほしいのですが、代わりに$i
を出力し続けます。これを解決するにはどうすればよいですか?
それは:
eval "$command"
$command
の内容をシェルコードとして評価する場合。
$command
が-
で始まらないことが保証できない場合(eval
のような一部のシェルではbash
がオプションとして扱われる可能性があります)、あなたは実行したいかもしれません:
eval " $command"
代わりに。この余分な先行スペースは、コマンドの解析方法に影響を与えず、$command
で始まる場合、-
がeval
のオプションとして扱われるのを防ぎます。 eval -- "$command"
は一部のシェル(bash
を含む)でも機能しますが、POSIX(IIRC)では機能せず、dash
やBourne Shellなどでは機能しません。
$command
はおそらく次のようになります:
command='echo "$i"'
$i
がsplit + globの対象になることを意図していない限り
コードを「変数」に格納するための潜在的に優れた方法は、関数を使用することです。
mycommand() { echo "$i"; }
(mycommand
はすでに既存のコマンドであるため、command
の代わりにcommand
を使用します)。
$command
がbreak
/continue
/return
の場合、動作はシェルによって異なります。
$command
に簡単なコマンドを保存したい場合は、Wordのリストで、最初にWordのリストを引数として実行するコマンドとして検索されます。配列変数を使用します。
command=('echo' '$i' "$i")
"${command[@]}"
これは、echo
を実行し、echo
、$i
および$i
の内容を引数として使用します。
command='echo $i ;x /* '$i
$command
(デフォルト値は$IFS
です)は、ほとんど意味がありません。そこで、$command
には文字列が含まれます。最初の$i
はそのままで、2番目は展開され(単一引用符の外側)、次にその文字列はsplit + globの対象になります($command
は二重引用符の内側ではないため)。 単純なコマンドとして再び扱われる単語の数になります。