最初の方法はなぜこのように動作しますか?

最初の方法はなぜこのように動作しますか?

シェルスクリプトをデバッグしようとしています。

content_type='-H "Content-Type: application/json"'
curl $content_type -d "{"test": "test"}" example.com

私はこれが私の期待に応えないことを学びました。このスクリプトでcurl渡されるパラメータは$content_type次のとおりです。

  1. -H
  2. "Content-Type:
  3. application/json"

(私が期待していたもの)代わりに:

  1. -H
  2. Content-Type: application/json

私は次のスクリプトを書くことができることを知っています。

content_type="Content-Type: application/json"
curl -H "$content_type" -d "{"test": "test"}" example.com

このように動作しますが、単一の変数にパラメータを含む複数のスペースを格納できるかどうかを知りたいです。

2番目の(動作)バージョンでは、コンテンツタイプを除外するには-H2つを削除する必要があります$content_type

ただし、オプションとその値を単一のエンティティに入れてコンテンツタイプを除外/含めると、単一のエンティティが削除/追加されるようにすることができるかどうかを知りたいです。

POSIXには配列がないため、配列を使用することは移植性がありません。

最初の方法はなぜこのように動作しますか?

なぜなら噴射。私たちが次のように定義するときcontent_type

content_type='-H "Content-Type: application/json"'

次の値を持ちます。

-H "Content-Type: application/json"

引用符なしで変数を引用すると(代わりに$content_type"$content_type"、拡張値がトークン化の対象になります。 ~から単語分割ページバッシュマニュアル:

シェルは、単語分割のために二重引用符内に表示されない引数拡張、コマンド置換、および算術拡張の結果をスキャンします。

同じページから:

シェルは各文字を$IFS区切り文字として扱い、これらの文字をフィールド終端として使用して、他の拡張結果を単語に分割します。 IFSが設定されていない場合、またはその値が次の場合 <space><tab><newline>...

したがって、-H "Content-Type: application/json"これを区切り文字として使用します。<space><tab><newline>これは私たちに以下を提供します。

-H
"Content-Type:
application/json"

ベストアンサー1

持つ一つ標準シェルの標準配列と同様の構造です。位置パラメータです。したがって、考えられる解決策はおよびset -- …を使用することです"$@"。あなたの場合は、次のことを行います。

set -- -H "Content-Type: application/json"
curl "$@" -d "{"test": "test"}" example.com

これは、使用可能なアレイを1つだけに制限することに注意してください。たとえば、1つはカールに使用され、もう1つは別のプログラムには使用できません。もちろん、スクリプトのパラメータは破損します。

おすすめ記事