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


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.