次のような関数を作成しようとしています。
作曲家-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では発生しない現象です)。
jq
UTF-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エンコーディングを完了する必要がありますjq
。ksh93
代わりにを使用している場合は、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
エンコードに注意してください。printf
jq
@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
。