一重引用符でパラメータを拡張する

一重引用符でパラメータを拡張する

次のような関数を作成しようとしています。

作曲家-config-repository.foo '{"type": "パス", "url": "/b/foo-bundle"}'

私から

lb() { composer config repositories.$1 '{"type": "path", "url": "/b/$1-bundle" }' ; }
lb foo

ただし、パラメータ(json文字列)が一重引用符内にあるため、foo-bundleの代わりに$ 1-bundleが生成されます。

この問題を回避する方法があると確信していますが、ハッキングすることはできません。

ありがとうございます。

答え1

$1文字通りjson文字列にコンテンツを挿入する代わりに、次のことができます。

lb() {
  composer config "repositories.$1" '
    {
      "type": "path",
      "url": "/b/'"$1"'-bundle"
    }'
}

jq正しいエンコーディングを使用してjsonを生成することもできます。

lb() {
  composer config "repositories.$1" "$(
    URL="/b/$1-bundle" jq -cn '
      {
        "type": "path",
        "url": $ENV.URL
      }')"
}

これは、JSON構文に特殊文字が含まれている場合$1にも機能します(URLでは発生しない現象です)。

jqUTF-8文字の一部にできないバイトは(U + FFFD)に変換されます文字を置き換える)。 JSON文字列には任意のバイトシーケンスを含めることはできず、UTF-8でエンコードされた文字のみを含めることができます。

とにかく、URLではこれらのバイトをエンコードする必要があります%XX。実際には文字列をURIにエンコードする演算子がjqあるので、次のことができます。@uri

lb() {
  composer config "repositories.$1" "$(
    URL="/b/$1-bundle" jq -cn '
      {
        "type": "path",
        "url": ($ENV.URL | @uri)
      }')"
}

しかし、残念ながらこれが適用されます後ろにしたがって、すべてのバイトシーケンス(UTF-8でデコードできないバイトシーケンスなど)を正しくURIエンコードできません。

前にURIエンコーディングを完了する必要がありますjqksh93代わりにを使用している場合は、bash組み込み関数を使用して実行できますprintf。たとえば、次のようになります。

function lb {
  typeset -x URL=${
    LC_ALL=C printf '%(url)q' "/b/$1-bundle"
  }
  composer config "repositories.$1" "${
    jq -cn '
      {
        "type": "path",
        "url": $ENV.URL
      }'
  }"
}

あるいは、適切なURI / JSON操作モジュールを持つプログラミングperl言語などの適切なプログラミング言語を使用できます。ruby

理想的でもそうでない場合もありますので、ksh93エンコードに注意してください。printfjq@uri/%2F

答え2

$1非常に強力な一重引用符でシェルを拡張することはできません。$1一重引用符を出る必要があります。一重引用符、二重引用符を閉じ、$1一重引用符をもう一度開くことができます。

… '{"type": "path", "url": "/b/'"$1"'-bundle" }'
#  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^      ^^^^^^^^^^  single-quoted, will be passed as-is
#                                ^^              double-quoted, will be expanded
# ^                            ^^  ^^          ^ quote removal will remove these

二重引用符も使用する必要があります。 $1()は他の場所に表示されますrepositories.$1

関連情報