Bash에서 달러 기호 평가에 큰따옴표를 넣는 이유는 무엇입니까? [복사]

Bash에서 달러 기호 평가에 큰따옴표를 넣는 이유는 무엇입니까? [복사]

작은 따옴표는 내부 내용을 평가하지 않지만 큰 따옴표는 평가한다는 것을 알고 있습니다. 사람들이 달러 기호를 인용하는 리뷰를 자주 봅니다. 여기 몇 가지 예가 있어요.

  • for i in "${indices[@]}"; do
  • if [ "${a}" == 0 ]; then
  • ffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4

달러 기호 표현을 큰따옴표로 묶지 않으면 어떻게 되나요? AFAIK, for루프는 여전히 작동합니다.

답변1

세 가지 예는 정확히 동일하지 않습니다.

마지막 두 개 중:

if [ "${a}" == 0 ]; then
ffmpeg -framerate 2 -pattern_type glob -i "*.png" -pix_fmt yuv420p output.mp4

$a인용되지 않고 해당 값에 문자 $IFS(기본적으로 공백, 탭 및 줄 바꿈) 또는 와일드카드가 포함된 경우 3개 이상의 인수( 및 [제외 )가 수신되며, 값이 비어 있는 경우에도 유사하게 오류가 발생합니다. 문자열로 인해 너무 적은 수의 매개변수를 받게 됩니다 .[]$a[

$ (a=0; [ $a == 0 ] && echo OK)
OK

(단, $IFS현재 포함되지 않은 경우에만 해당 0)

$ (a='foo bar'; [ $a == 0 ] && echo OK)
bash: [: too many arguments

(기본값은 $IFS)

$ (a=; [ $a == 0 ] && echo OK)
bash: [: ==: unary operator expected

(비어 있거나 $IFSwith를 사용하더라도 zsh(그렇지 않으면 암시적 분할+glob 연산자가 인용되지 않은 확장에서 구현되지 않음))

$ (a='*'; [ $a == 0 ] && echo OK)
bash: [: too many arguments

(숨겨지지 않은 파일이 2개 이상 포함된 디렉터리에서 실행하는 경우)

참고로 오류는 없습니다.

$ (a='foo bar'; [ "$a" == 0 ] && echo OK)
$ (a=; [ "$a" == 0 ] && echo OK)

첫 번째 예는 다릅니다. a배열 이 포함된 경우 큰따옴표 안의 확장 규칙은 특별합니다 .

  • $a배열의 첫 번째 요소입니다. 엄밀히 말하면 ${a[0]}인덱스 0의 요소가 정의되지 않은 경우에도 마찬가지입니다.

  • ${a[*]}또는${a[@]} 추가로 분할되는 배열 요소 $IFS(기본적으로 공백, 탭, 개행);

  • "${a[@]}"에서 분할되지 않은 배열의 요소입니다 $IFS.

따라서 루프는 for i in "${indices[@]}"; do ...배열의 내용에 따라 실제로 동일하지 않습니다. 예를 들어:

$ (declare -a a=(a b c); printf '%s\n' $a)
a

$ (declare -a a=(a b c); printf '%s\n' ${a[*]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' ${a[*]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' ${a[@]})
a
b
c

$ (declare -a a=(a 'b c'); printf '%s\n' "${a[*]}")
a b c

$ (declare -a a=(a 'b c'); printf '%s\n' "${a[@]}")
a
b c

답변2

간단히 말해서 이는 변수에 존재할 수 있는 특수 문자(예: )로 인한 확장을 방지하기 위해 수행됩니다 !. 특정 문자(달러 기호, 백틱 및 백슬래시)가 해석되므로 큰따옴표를 "약한 따옴표"라고도 합니다. 작은따옴표는 "강한 따옴표"이며 어떤 것도 해석하지 않습니다.

인용하다배쉬 문서:

3.1.2.3 큰따옴표

문자를 큰따옴표( )로 묶으면 , 및 (기록 확장이 활성화된 경우)를 제외한 따옴표 안의 모든 문자의 리터럴 값이 유지됩니다 ". 쉘이 POSIX 모드에 있을 때(Bash POSIX 모드 참조), 히스토리 확장이 활성화된 경우에도 큰따옴표 안에 특별한 의미가 없습니다.$backquote\!!

약한 참조와 강한 참조의 예:

  • echo "Your PATH is: $PATH"- 인쇄됩니다Your PATH is:<variable_content>
  • echo 'Your PATH is: $PATH'- 인쇄됩니다Your PATH is: $PATH

귀하의 질문에 답변하기 위해 변수에 큰따옴표를 사용하여 확장을 허용 $하지만 변수 내용이 더 이상 확장되지 않도록 합니다.

관련 정보:

관련 정보