작은따옴표로 매개변수 확장

작은따옴표로 매개변수 확장

다음을 수행하는 함수를 만들려고합니다.

작곡가-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 인코딩을 완료해야 합니다 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인코딩에 주의를 기울이십시오 .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.

관련 정보