Bash: 배열을 사용하지 않고 여러 인수가 포함된 변수 내에서 공백으로 쉘 인수를 인용하는 방법은 무엇입니까? [복사]

Bash: 배열을 사용하지 않고 여러 인수가 포함된 변수 내에서 공백으로 쉘 인수를 인용하는 방법은 무엇입니까? [복사]

Bash에서는 따옴표 안의 공백으로 분할하지 않고 적절하게 인용된 옵션 목록을 사용하여 명령에 변수를 전달할 수 있습니까? IOW, 이 스크립트는 다음과 같습니다.

MYCONFIG="--hi FOO=bar 'X=ABC 123'"
printf '[%s]\n' $MYCONFIG

산출:

[--hi]
[FOO=bar]
['X=ABC]
[123']

내가 출력하고 싶은 것은

[--hi]
[FOO=bar]
['X=ABC 123']

배열로 이 작업을 수행할 수 있다는 것을 깨달았습니다.또는함수로, 하지만 저는 함께 일하고 있어요인수를 보유하기 위해 이미 문자열 변수 생성에 의존하는 스크립트. 될 수 없다기능으로 교체스크립트의 다른 사용자는 오류를 받게 되기 때문입니다.

따옴표 붙은 문자열 내의 공백이 손상되는 것을 방지하기 위해 올바른 따옴표로 문자열을 구성하는 것이 가능합니까?

실패하면 어떻게 수정할 수 있나요?스크립트어레이 구성과 기존 문자열 구성을 지원합니다. 둘 중 하나를 다른 것으로 변환할 수도 있나요?

답변1

에서는 zsh다음을 수행합니다.

$ MYCONFIG="--hi FOO=bar 'X=ABC 123'"
$ printf '[%s]\n' ${(z)MYCONFIG}
[--hi]
[FOO=bar]
['X=ABC 123']
$ printf '[%s]\n' "${(Q@)${(z)MYCONFIG}}"
[--hi]
[FOO=bar]
[X=ABC 123]

매개 z변수 확장 플래그는 셸 토큰화를 사용하여 입력을 중단하고(zsh 구문을 기반으로 하며 이 플래그는 z주석 또는 개행 처리 플래그를 사용하여 조정할 수도 있습니다. 세부 정보 참조) 첫 번째 수준 참조를 제거합니다.Zinfo zsh flagsQ

에서는 bash언제든지 다음을 수행할 수 있습니다.

readarray -td '' words < <(
  export MYCONFIG
  zsh -c 'print -rNC1 -- ${(z)MYCONFIG}'
)
printf '[%s]\n' "${words[@]}"

zshNUL로 구분된 단어를 토큰화 하고 전달합니다 bash.

이 경우 플래그를 추가하는 것은 추가 NUL을 추가하는 포함 Q과 마찬가지로 문제가 될 수 있습니다 . 그러나 어쨌든 변수 content 에 NUL을 가질 수 없다는 사실과는 반대로 NUL을 제거 하는 것이 좋습니다 .$MYCONFIG$'\0'bashzshzsh

readarray -td '' words < <(
  export MYCONFIG
  zsh -c '
    quoted_words=( ${(z)MYCONFIG} )
    unquoted_words=( "${(Q@)quoted_words}" )
    without_nul=( "${(@)unquoted_words//$'\''\0'\''}" )
    print -rNC1 -- "${without_nul}"
  '
)

답변2

약간 조정하면(작은따옴표를 희생해야 함):

xargs -n1 printf "[%s]\n" <<<"$MYCONFIG"
[--hi]
[FOO=bar]
[X=ABC 123]

유틸리티 는 플래그로 매개변수를 구별 xargs할 수 있습니다 -n. 불행하게도 이 -I플래그는 인용되지 않은 공백으로 인한 분할을 허용하지 않습니다.

관련 정보