我正在尝试创建一个执行以下操作的函数
作曲家配置存储库.foo'{“type”:“path”,“url”:“/b/foo-bundle”}'
我从
lb() { composer config repositories.$1 '{"type": "path", "url": "/b/$1-bundle" }' ; }
lb foo
但因为参数(json 字符串)位于单引号内,所以它生成 $1-bundle 而不是 foo-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
}')"
}
这样,即使$1
包含 JSON 语法中的特殊字符(而不是 URL 应该发生这种情况),它也可以正常工作。
请注意,jq
将不能作为 UTF-8 字符一部分的字节转换为�
(U+FFFD替换字符)。 JSON 字符串不能容纳任意字节序列,只能容纳 UTF-8 编码的字符。
无论如何,在 URL 中,这些字节应编码为%XX
.jq
确实有一个@uri
运算符对字符串进行 URI 编码,因此您可以执行以下操作:
lb() {
composer config "repositories.$1" "$(
URL="/b/$1-bundle" jq -cn '
{
"type": "path",
"url": ($ENV.URL | @uri)
}')"
}
然而,不幸的是,这将适用后的翻译�
,因此不会让您正确地对任何字节序列进行 URI 编码(例如无法解码为 UTF-8 的字节序列)。
您需要在 之前完成 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
}'
}"
}
或者您可以使用适当的编程语言,例如perl
或ruby
带有适当 URI / JSON 操作模块的语言。
请注意ksh93
' s 的编码printf
,因为这可能是理想的,也可能不是理想的。jq
@uri
/
%2F
答案2
您无法使 shell$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
)。