[[]] 테스트에서 큰 따옴표를 사용하는 이유는 무엇입니까?


23

bash 스크립트에 2 개의 정수가 있다고 가정 해 봅시다.

value1=5
value2=3

그렇다면 왜 테스트 할 때 큰 따옴표를 사용해야합니까? 예를 들면 다음과 같습니다.

if [[ "$value1" -eq "$value2" ]]

왜 다음을 사용하지 않습니까?

if [[ $value1 -eq $value2 ]]

나에게 큰 따옴표는 의미가 없습니다.


5
쉘에서 인용하는 것은 문자열과 거의 관련이 없습니다 (데이터 유형에서와 같이). 쉘이 단어 분할 (및 다른 종류의 확장)을 수행하지 못하게하는 것과 관련이 있습니다.
— filbranden

13
terdon이 지적 했듯이이 특정 구문에서 변수를 인용 할 필요 는 없지만 (물론 어느 곳에서나 한 단어 값을 갖는 경우) 항상 var를 인용 하도록 조언하고 싶습니다 . 어떤 상황에서도 변수를 인용 부호로 남겨 둘 수 있다는 것을 알고 있습니까? 5및로 불필요하더라도 인용해야 할 이유 3는 유지 보수 가능성입니다. 값이 나중에 변경 될 수 있으며 결과 오류가 명확하지 않을 수 있습니다.
— 베드로-모니카 복원

2
@sudodus 나는에 대한 사실 생각하지 않습니다 [[ ]]만 들어 [ ].
— Benjamin W.

1
당신은 맞습니다, @BenjaminW. 변수에 큰 따옴표를 사용하는 것이 좋은 이유는 단어 분할이 유일한 경우는 아닙니다. 변수가 비어있는 경우도 있습니다. 이렇게하면 []의 문이 실패합니다 (예 : 오류가있는 [2 -eq], [[]]는 취약하지 않습니다 (단어 분리의 경우와 같이)
— sudodus

2
@marcelm, Bash, ksh 및 Zsh는 정수 변수를 가지며 그 안에서 [[ ]]피연산자 -eq를 정수로 강제 변환합니다 .
— ilkkachu

답변:


7

단어 분리.

이 예제는 매우 불가능 하지만 가능 하기 때문에 방어 적으로 코딩하려면 트랙을 따옴표로 묶으십시오.

$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'

좋아, 지금까지는 모두 좋아 렌치를 기어에 넣습니다.

$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected

죄송합니다.

$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'

아


2
그러나 OP는 이중 괄호를 사용하므로 단어 분할이 발생하지 않습니다.
— user000001

5
예, 이것은 bash의 [[ ]]구성 과 실제로 관련이 없습니다 .
— terdon

1
뭐라고? [ $value1 -eq $value2 ]비어 있으면 왼쪽에 없는 value1것 입니다. '[' -eq 3 ']'''
— Charles Duffy

나도 놀랐지 만 증거가 있습니다.
— glenn jackman

1
이 답변은 질문과 직접 관련 이 없습니다 . 나는 그것이 받아 들여 졌다는 것에 놀랐다. 커뮤니티 위키로 설정
— glenn jackman

35

실제로 여기에 따옴표가 필요하지 않습니다. 인용되지 않은 변수를 사용하는 것이 안전한 경우는 매우 드 few니다. 당신은 이것을 확인할 수 있습니다 set -x:

$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!

위에서 볼 수 있듯이 따옴표로 묶인 인용 부호와 인용 부호가없는 버전의 테스트는 똑같이 해결됩니다. 연산자 zsh를 지원하는 다른 쉘에서도 마찬가지입니다 [[ ]].

더 이식성이 좋은 경우 는 아닙니다[ ] .

$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!

[ ]구조는 달리 [[ ]]하나, 인용이 필요 없습니다.


인용이 필요한시기와 이유에 대한 자세한 정보를 제공하는 유용한 링크 :


이 경우 정수 변수를 사용하면 선언하는 것이 좋습니다. declare -i var1=인 0평가 때.
— 프레디

4
참고 -eq입니다 산술 당신도 떠날 수 있도록, 비교 $(아웃을 [[ .. ]]), 및 쓰기 [[ a -eq b ]]. 문자열 비교를 위해서는 $물론 다음이 필요합니다 .[[ $a = $b ]]
— ilkkachu

2
@ user000001 좋은 지적입니다. 물론 확장 된 것을 원할 수도 있습니다 . 예를 들어 이것이 일치하는 것으로 기대합니다 var1="afoob"; var2="a*b"; [[ $var1 = $var2 ]] && echo match. globbing 컨텍스트 (예 :)에서 glob 역할을하지 않고 glob 문자를 사용하려면 [[ ]]인용해야합니다.
— terdon

3
@ilkkachu, 저를 놀라게합니다. "베어"변수는 배열 첨자 또는 ((...))또는 내에서만 고려 될 것이라고 생각했습니다 $((...). 그것은 작동하는 것처럼 보이지만 (오래된 심술쟁이, 가능하게) 나는 그것을 좋아하지 않습니다.
— glenn jackman 16:15에

1
@glennjackman, 글쎄, 당신에게 말할 수있는 것이 유감이지만, 그래도 피연산자 -eq와 친구 [[ ]]도 산술 컨텍스트입니다. :) (관련 : bash [[]] 명령 내 자동 변수 확장 )
— ilkkachu

17

큰 따옴표가 필요하지 않지만 사용하는 이유는 다음과 같습니다.

  • 모범 사례 / 습관 : 이 경우에는 필요하지 않지만 일반적으로 큰 따옴표 는 의도하지 않은 단어 분리를 피하는 것입니다.
  • 때문에 value1와 value2변수, 그리고 당신이 포함 된 내용을 알고하지 않을 수 있습니다. 그렇지 않으면 "왜 검사하지 않고 변수로 귀찮게 if [[ 5 -eq 3 ]]하는가? 더 자세히 살펴보면 if5가 3과 같지 않다는 것을 이미 알고있을 때 왜 귀찮게 하는가?" 단어 분리는 발생 [[하지 않지만 단어 분리가 발생 하지 않는 경우는 드물다.

1

귀하의 질문과 직접 ​​관련이 없지만

if (($ value1 == $ value2)); 그때

숫자를 비교할 때 따옴표를 사용할 필요가 없습니다.


2
if (( value1 == value2 )); then. 산술 문맥에서는조차 필요하지 않습니다 $. 그러나이 질문은 [[ ... ]]테스트에 사용 된 변수에 초점을 맞추는 것 같습니다 .
— Kusalananda

1
알아. 그러나 변수 이름의 일관성을 유지하고 항상 접두사로 $를 사용하기 때문에 솔직히이 기능을 사용하지 않습니다.
— 경련

1

너가 확실히 맞아!

이중 대괄호 안의 인용은 적어도이 경우에는 의미가 없습니다.

그러나 매일 큰 따옴표를 사용하기 때문에-특히 단일 대괄호 표현식, 함수 및 스크립트에 인수 전달, 때로는 변수 할당 (간단한 분리에는 쓸모가 없음)- 적어도 일부 사람들은 추측합니다. 변수 확장을 본능적으로 큰 따옴표로 묶습니다 .

큰 따옴표는 절약 감을 줄 수 있습니다. 큰 따옴표가있는 집에 오는 것과 같습니다. -D. Kummer

큰 따옴표를 결과적으로 그리고 이해하기 쉬운 방식 으로하는 것의 이점은 , 이해가 되겠지만, bash를 처음 접하는 동료들은 보다 안정적인 스크립트를 작성하는 방법을 배울 수 있다는 것 입니다. 또한 bash를 사용한 데이터 처리 기술은 필드 구분 기호로 데이터 스트림 (변수 포함)을 분리하고 필터를 통해 파이프하는 것 보다 더 중요 하다는 사실을 강조합니다 . 데이터 청크를 스트림에서 분리하자마자 큰 따옴표로 묶으십시오!

또 다른 이점은 코드 강조 편집기 내에서 큰 따옴표로 묶인 문자열이 있는 bash 스크립트의 가독성이 향상 될 수 있다는 것입니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.