Bashからスクリプトを呼び出すときにパラメータの問題があります。

Bashからスクリプトを呼び出すときにパラメータの問題があります。

XMLファイルを生成し、Perlスクリプトを実行して一連のパラメータを渡すスクリプトがあります。これはキーコードです:

CMD="./dnscurl.pl --keyname $KEYNAME  -- -X POST -H \"Content-Type: text/xml; charset=UTF-8\" --upload-file /tmp/file.xml https://route53.amazonaws.com/2010-10-01/hostedzone/$HZID/rrset"
echo "Executing..."
echo $CMD
RESULT=`$CMD`

実行すると、-Hパラメータがdnscurl.plスクリプトに送信された後に含まれるパラメータに問題が発生したことがわかりました。

curl:(6)ホストの「テキスト」を解析できません。

しかし、私がエコーした正確なコマンドを得ることができ、シェルプロンプトでそれを実行すると、スクリプトは正しく実行されます。バックティックでRESULT =を使用して実行すると、パラメータは$CMD「Content-Type:etc...」の周囲の二重引用符で渡されないようです。

私が実行しているコマンドは次のとおりです(キー名とホストIDパラメータのみが変更されます)。

./dnscurl.pl --keyname mykey -- -X POST -H "Content-Type: text/xml; charset=UTF-8" --upload-file /tmp/file.xml https://route53.amazonaws.com/2010-10-01/hostedzone/ZZZZZZZ/rrset

私が気になったことの1つは、「--」を使用することです。私はこれがdnscurl.plスクリプトによって具体的に処理されることを知っていますが、それが渡される理由は明らかではありません。位置パラメータ処理がバイパスされたためですか?このスクリプトは、3つの異なるユースケースを処理するように書かれています。私はこれが関係ないと思いますが、完全性のために、このスクリプトはAWSのRoute 53 Rest APIを呼び出すために使用されます。

ベストアンサー1

引用が間違っています。引用符なしで作成すると、$CMD値は$CMDスペースの各シーケンスで「単語」に分割され(単語には句読点を含むスペース以外の文字を含めることができます)、各単語はワイルドカードに展開されます(つまり、ワイルドカード拡張)。特に、値の引用符はCMD変更されません。引用符はシェルスクリプト構文では意味がありますが、変数置換では意味がありません。その後、最初の単語は実行するコマンドの名前になり、次の単語はコマンドの引数になります。

あなたの例で$KEYNAMEissomekeyname$HZIDisと仮定すると、somehzidコマンドとパラメータは次のようになります。

./dnscurl.pl
--keyname
$KEYNAME
--
-X
POST
-H
"Content-Type:
text/xml;
charset=UTF-8"
--upload-file
/tmp/file.xml
https://route53.amazonaws.com/2010-10-01/hostedzone/somehzid/rrset

パラメータはtext/xml;オプションではなく最初のパラメータとして表示されます。 Perlスクリプトはそのパラメータをcurlパラメータリストに渡し、--あなたの質問とは関係ありません。

コマンドラインを変数に入力できません。 (単純)変数は無効なツールです。変数には文字列が含まれていますが、コマンドラインは文字列(コマンドとその引数)のリストです。コマンド名とそのパラメータを配列変数に入力できます。

CMD=(./dnscurl.pl --keyname "$KEYNAME"  --
     -X POST -H "Content-Type: text/xml; charset=UTF-8"
     --upload-file /tmp/file.xml
     "https://route53.amazonaws.com/2010-10-01/hostedzone/$HZID/rrset")
RESULT=$("${CMD[@]}")

奇妙な構文のように見えることは、"${CMD[@]}"配列変数をCMD配列の単語リストに展開します。二重引用符は、配列内の単語の拡張を防ぎ、[@]歴史的な理由で配列を拡張しようとしていることをシェルに通知するために必要です。

後で使用するためのコマンドラインまたはランダムシェルの断片を覚えておくもう1つの方法は関数です。

cmd () {
    ./dnscurl.pl --keyname "$KEYNAME"  -- \
                 -X POST -H "Content-Type: text/xml; charset=UTF-8" \
                 --upload-file /tmp/file.xml \
                 "https://route53.amazonaws.com/2010-10-01/hostedzone/$HZID/rrset"
}
RESULT=$(cmd)

より正確には の値に応じてIFS

おすすめ記事