Bash

在單引號內擴展參數

  • June 8, 2022

我正在嘗試創建一個執行以下操作的函式

composer config repositories.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到您可以使用的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, like jq’ 的@uri編碼可能是可取/%2F,也可能不是可取的。

引用自:https://unix.stackexchange.com/questions/705445