매개 변수 목록을 작성하는 데 사용되는 배시 문자열 연결


12

이 bash 조각이 주어지면 :

PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo $PARMS
rsync ${PARMS} . ${TARGET}

echo는 PARMS 문자열을 예상대로 표시하지만 오류는 표시되지 않지만 rsync는 + =로 추가 된 옵션이없는 것처럼 자동으로 작동합니다. 그러나 이것은 예상대로 작동합니다.

PARMS='-rvu'
rsync ${PARMS} --delete --exclude='.git' . ${TARGET}

나는 bash 따옴표 (항상 문제가 있음)로 무언가를 망쳐 놓았지만 문자열이 올바르게 작성된 것처럼 보이지만 옵션이 무엇과 왜 무시되는지 정확히 알지 못합니다.


1
echo "$PARMS"rsync "${PARMS}"...
jasonwryan

이것은 bash버전 4.2.25에서 아무런 변화없이 작동합니다 .
Anthon

답변:


17

다음과 같은 차이점이 있습니다.

PARMS+="... --exclude='.git'"

... --exclude='.git'

첫 번째로 작은 따옴표는 따옴표 자체 안에 있으므로 문자 그대로rsync 인수로 지정된 대체 텍스트에 표시됩니다 . rsync값이 인 인수를 가져옵니다 --exclude='.git'. 두 번째에서 작은 따옴표는 그들이 있기 때문에, 그들이 작성하고있는 시점에서 쉘에 의해 해석 되지 않습니다 따옴표 안에 자신을, 그리고 rsync볼 얻는다 --exclude=.git.

이 경우 작은 따옴표가 필요하지 않습니다. .git특수 문자없이 자체적으로 완벽하게 유효한 셸 단어이므로 명령에 그대로 사용할 수 있습니다.

그러나 이런 종류의 것에 더 나은 것은 배열입니다 .

PARMS=(-rvu)
PARMS+=(--delete --exclude='.git')
rsync "${PARMS[@]}"

이것은 배열 줄을 쓸 때 해석하려는 인용 부호와 함께 명령을 별도의 단어로 작성합니다. 인수 자체에 특수 문자 나 공백이 있어도 배열의 각 항목을 별도의 인수로 "${PARMS[@]}"확장 하므로 rsync의도 한대로 작성한 내용을 봅니다.


bash${PARMS}확장 후 단어 분할을 수행했습니다 . 따라서 작은 따옴표도 쉘에서 해석되었습니다.
cuonglm

2
시도 해봐! 나는했다. 따옴표는 그대로 남아 있으며 그 사이에 공백이 있으면 어쨌든 분리 점이 있습니다.
Michael Homer

@Gnouc : bash는 남자 페이지에서 "견적 제거 : 이전 확장 후, 모든 문자 인용 부호가 발생 \ , '". 제거 위의 확장 중 하나에서 발생하지 않았다" "확장 위"에는의 확장을 수행하는 매개 변수 확장이 포함됩니다 ${PARMS}.
camh

감사. 따라서이 경우 이중 따옴표 안의 작은 따옴표를 생략하면 효과가 있지만 완전성을 위해 작동합니다. 특수 문자를 인용해야하고 후자의 접근법을 사용하고 싶지 않은 경우 어떻게해야합니까?
neuviemeporte

특수 문자가 IFS(일반적으로 공백)의 일부가 아닌 경우 따로 인용 할 필요가 없습니다. 만약 그렇다면, 무언가를 해킹하지 않으면 운 eval이 나빠질 것입니다. 이것은 일반적으로 약간의 오해이며, 배열은 그것을 처리하는 올바른 방법입니다.
Michael Homer

2

@Michael Homer의 답변 외에도 bash eval 함수를 사용할 수 있습니다 .

PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo "$PARMS"
eval "rsync ${PARMS} . "'"${TARGET}"'

2
할 수는 있지만해서는 안됩니다. 이 사용을 피하기 위해 배열이 특별히 추가되었습니다 eval.
chepner
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.