次の例があります。
#!/bin/bash
ARGUMENTS="-executors 1 -description \"The Host\" "
# call1
# error: parameter Host" is not allowed
java -jar swarm-client.jar $ARGUMENTS
# call2
# works fine with eval
eval java -jar swarm-client.jar $ARGUMENTS
から$ARGUMENTS
私は主張を引用します。引用の問題を解決するcall1
理由を理解できません。eval
シェルのコマンド評価のプロセスと順序を理解していないようです。私に説明してもらえますか?
ベストアンサー1
あなたはしません引用された引数を渡すコマンドの場合、引数を渡すことができます。
入力するとき:
cmd arg1 arg2
シェルは、スペースが単語区切り文字である独自の構文で行を解析し、引数としてcmd1
呼び出されます。cmd
arg1
arg2
ノート:cmd
引数に空白文字を許可しません。スペースはシェル言語構文の演算子にすぎません。
Cと同様に、func("foo", "bar")
実行時に2つのポインタ引数を受け取って作成した場合、または空白文字はfunc
表示されません。(
,
"
シェル構文の一部も引用されます。"
シェル構文の他の部分を含む文字を含むことができる単語に使用されます。
これを行うとき:
cmd "arg 1" arg2
cmd
cmd
、arg 1
およびarg2
引数を受け取ります。何の文字も見えません"
。これは"
、シェル構文でスペースが単語区切り文字として扱われないようにするために使用されます。
今これを行う:
cmd $VAR
これは次のこととは異なります。
cmd the content of the variable
その場合、問題が発生します。
VAR='foo; reboot'
echo $VAR
例えば。
Bourne のようなシェルではの内容がどちら$VAR
にも単一引数で逐語的に渡されません (残念ながらこの問題は、およびそれより少ないcmd
一部の他のシェルでは修正されました)。rc
代わりに、分割とワイルドカード()が適用され、結果の単語がに渡されます。es
fish
zsh
split+glob
cmd
$IFS
分割は、デフォルトではスペース、タブ、および改行を使用する特殊変数の文字に基づいています。
$ARGUMENTS
含まれている内容については、、で-executors 1 -description "The Host"
区切ります。これらの単語にはワイルドカードが含まれていないため、glob部分は適用されないため、これらの単語はに渡されます。-executors
1
-description
"The
Host"
cmd
ここでは、演算子を使用し、split+glob
その単語に表示されない文字を区切り文字として使用して部分を分割できます。
ARGUMENTS='-executors|1|-description|The Host'
IFS='|'
cmd $ARGUMENTS
または、これをサポートするシェル(例bash
:)の場合はより良いです。配列の使用、これらのパラメータをすべて含む変数を含めることができます。
eval
シェルコードを評価することです。したがって、別のオプションは、ARGUMENTS
シェルコード(引数リストではなくシェル構文のテキスト)を含め、それをeval
解釈に渡すことです。しかし、分割+グローブ演算子を避けるために変数を引用することを忘れないでください。
eval "cmd $ARGUMENTS"