${variable_name}당신이 생각하는 그런 의미는 아니죠...

${variable_name}당신이 생각하는 그런 의미는 아니죠...

단일 또는 이중 괄호를 사용하는 것이 혼란스럽습니다. 이 코드를 보세요:

dir="/home/mazimi/VirtualBox VMs"

if [[ -d ${dir} ]]; then
    echo "yep"
fi

문자열에 공백이 포함되어 있어도 정상적으로 작동합니다. 하지만 단일 대괄호로 변경하면 다음과 같습니다.

dir="/home/mazimi/VirtualBox VMs"

if [ -d ${dir} ]; then
    echo "yep"
fi

그것은 말한다:

./script.sh: line 5: [: /home/mazimi/VirtualBox: binary operator expected

내가 그것을 다음과 같이 바꿀 때 :

dir="/home/mazimi/VirtualBox VMs"

if [ -d "${dir}" ]; then
    echo "yep"
fi

좋은 결과. 무슨 일인지 설명해 줄 수 있는 사람이 있나요? 예를 들어 "${var}"공백으로 인한 문제를 방지하려면 언제 변수 주위에 큰따옴표를 지정해야 합니까 ?

답변1

단일 대괄호는 [실제로 명령의 별칭입니다 test.아니요통사론.

단일 괄호의 단점 중 하나는 평가하려는 피연산자 중 하나 이상이 빈 문자열을 반환하는 경우 두 개의 피연산자(이진수)가 필요하다고 불평한다는 것입니다. 이것이 바로 사람들 이 피연산자가 빈 문자열로 평가되지 않도록 보장하면서 [ x$foo = x$blah ]이렇게 하는 것을 보는 이유입니다 .x

[[ ]]반면에 이중 괄호는문법이야그리고 [ ]. 발견한 대로 "피연산자 누락" 문제가 발생하지 않으며 C와 유사한 연산자 구문도 더 많이 허용합니다 >, <, >=, <=, !=, ==, &&, ||.

내 조언은 이렇습니다: 만약 당신의 통역사 #!/bin/bash언제나사용[[ ]]

[[ ]]모든 POSIX 쉘이 이를 지원하는 것은 아니지만 많은 쉘이 이를 지원한다는 zsh점 은 주목할 가치가 있습니다 .kshbash

답변2

[명령은 일반적인 명령입니다. 대부분의 쉘은 효율성을 위해 내장 함수로 제공하지만 쉘의 일반 구문 규칙을 따릅니다. 필수가 아닌 마지막 인수로 a가 필요 하다는 점을 제외하면 [와 정확히 동일합니다 .test[]test

이중 괄호는 [[ … ]]특수 구문입니다. 사용이 번거롭고 쉘 특수 문자에 몇 가지 새로운 추가 기능을 허용하기 때문에 ksh(몇 년 후 [) 에 도입되었습니다. 예를 들어 다음과 같이 쓸 수 있습니다.[[[

[[ $x = foo && $y = bar ]]

전체 조건식은 쉘에 의해 구문 분석되므로 while 은 먼저 연산자로 구분된 [ $x = foo && $y = bar ]두 개의 명령으로 분할됩니다 . 마찬가지로 이중 괄호를 사용 하면 값이 ;로 시작하는지 테스트하는 등의 패턴 일치 구문과 같은 작업이 가능합니다 . 단일 괄호 안에 있으면 현재 디렉터리의 이름으로 시작하는 파일 목록이 확장됩니다 . 이중 괄호는 ksh에서 처음 도입되었으며 ksh, bash 및 zsh에서만 사용할 수 있습니다.[ $x = foo$y = bar ]&&[[ $x == a* ]]xaa*a

작은 괄호 안에는 대부분의 다른 위치에서와 마찬가지로 변수 대체 주위에 큰따옴표를 사용해야 합니다. 이는 명령에 대한 인수일 뿐이기 때문입니다( command [). 큰 괄호 안에는 큰따옴표가 필요하지 않습니다. 쉘은 단어 분리나 와일드카드를 수행하지 않기 때문입니다. 이는 명령이 아닌 조건식을 구문 분석하는 것입니다.

한 가지 예외는 [[ $var1 = "$var2" ]]바이트 간 문자열 비교를 수행하려는 경우 따옴표가 필요하다는 것입니다. 그렇지 않으면 $var2일치하는 패턴이 됩니다 $var1.

당신이 할 수 없는 한 가지는 [[ … ]]변수를 연산자로 사용하는 것입니다. 예를 들어, 다음은 완전히 합법적이지만 거의 유용하지 않습니다.

if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
if [ "$x" "$op" "$y" ]; then …

귀하의 예에서

dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …

내부 명령에는 , , 4 개의 매개변수가 if있습니다 . 쉘은 그것을 구문 분석한 후에 무엇을 해야 할지 모릅니다 . 올바른 형식의 명령을 얻으려면 단어 분리를 방지해야 합니다 .[-d/home/mazimi/VirtualBoxVMs]-d /home/mazimi/VirtualBoxVMs${dir}

일반적으로 결과에 대해 토큰화 및 와일드카드를 수행하려는 경우가 아니면 항상 변수 및 명령 대체 주위에 큰따옴표를 사용하십시오. 큰따옴표를 사용하지 않는 것이 안전한 주요 위치는 다음과 같습니다.

  • 할당에서: (그러나 foo=$bar예를 들어 배열 할당 내에서는 큰따옴표가 필요합니다.)export "foo=$bar"array=("$a" "$b")
  • case성명서 에서 : case $foo in …;
  • =or 연산자의 오른쪽을 제외한 이중 괄호 내 ==(실제로 패턴 일치가 필요한 경우 제외): [[ $x = "$y" ]].

모두 큰 따옴표를 사용하는 것이 정확하므로 고급 규칙을 건너뛰고 항상 따옴표를 사용하는 것이 좋습니다.

답변3

"${var}"예를 들어 공백으로 인한 문제를 방지하려면 언제 변수 주위에 큰따옴표를 지정해야 합니까 ?

이 질문에 암시적인 것은

왜 충분하지 않습니까?${variable_name}

${variable_name}당신이 생각하는 그런 의미는 아니죠...

...그렇다고 생각한다면아무것변수 값에서 공백이나 "glob"(파일 이름 패턴) 문자로 인해 발생한 문제를 처리합니다. 이것에 좋습니다:${variable_name}

$ bar=foo
$ bard=Shakespeare
$ echo $bard
Shakespeare
$ echo ${bar}d
food

다른 건 없어!1   하지마${variable_name}어느A변수 이름의 일부일 수 있는 문자(문자( - Z또는 a- z), 밑줄( _) 또는 숫자( 0- )) 가 뒤에 오지 않는 한 괜찮습니다 9. 그럼에도 불구하고 문제를 해결할 수 있습니다.

$ echo "$bar"d
food

또는

$ fourth_letter=d
$ echo $bar$fourth_letter
food

나는 그것의 사용을 막으려는 것이 아니라( echo "${bar}d"아마도 최선의 해결책일 것입니다) 사람들이 교정기에 의존하는 것을 막으려는 것입니다.바꾸다따옴표를 사용하거나 본능적으로 중괄호를 사용하여 “이제 따옴표가 필요한가요?반품?"  타당한 이유가 없고 자신이 하고 있는 일을 확실히 알고 있지 않는 한 항상 따옴표를 사용해야 합니다.
________________ 1    물론 다음과 같은 경우는
제외됩니다 .매개변수 확장, , 및 , 와 같은 문법은 문법을 기반으로 합니다. 또한 등을 사용하여 10번째, 11번째 등의 위치 매개변수를 인용해야 합니다. - 인용은 이에 도움이 되지 않습니다.${parameter:-[word]}${parameter%[word]}${#parameter}${parameter^^}${parameter}${10}${11}

답변4

변수에서 공백과 공백 | 특수 문자를 처리하려면 항상 큰따옴표로 묶어야 합니다. 적절한 IFS를 설정하는 것도 좋은 방법입니다.

존경받는다: http://www.dwheeler.com/essays/filenames-in-shell.html

관련 정보