扩展单引号内的参数

扩展单引号内的参数

我正在尝试创建一个执行以下操作的函数

作曲家配置存储库.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
      }'
  }"
}

或者您可以使用适当的编程语言,例如perlruby带有适当 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)。

相关内容