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


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

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

  • 모범 사례 / 습관 : 경우에는 필요하지 않지만 일반적으로 큰 따옴표 의도하지 않은 단어 분리를 피하는 것입니다.
  • 때문에 value1value2변수, 그리고 당신이 포함 된 내용을 알고하지 않을 수 있습니다. 그렇지 않으면 "왜 검사하지 않고 변수로 귀찮게 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.