bash에서 큰 따옴표와 큰 따옴표가 없는 것의 차이점은 무엇입니까

bash에서 큰 따옴표와 큰 따옴표가 없는 것의 차이점은 무엇입니까

bash 스크립트가 있는데 그 중 하나에 다음이 포함되어 있습니다.

#!/bin/bash
source $(dirname ${BASH_SOURCE[0]})/script.sh

그리고 기타 내용은 다음과 같습니다.

#!/bin/bash
source "$(dirname ${BASH_SOURCE[0]})/script.sh"

이러한 스크립트는 어떻게 다르게 동작하며 그 이유는 무엇입니까? 무엇차이점?

답변1

따옴표가 없는 문자열은 다음으로 보호됩니다.분사그리고와일드카드. 당신은 또한 볼 수 있습니다배쉬 트랩 #14.

비교하다

$ echo $(printf 'foo\nbar\nquux\n*')
foo bar quux ssh-13yzvBMwVYgn ssh-3JIxkphQ07Ei ssh-6YC5dbnk1wOc 

그리고

$ echo "$(printf 'foo\nbar\nquux\n*')"
foo
bar
quux
*

단어 분할이 발생하면 첫 번째 문자가 IFS구분 기호(기본적으로 공백) 역할을 합니다.

거의 모든 경우에 따옴표를 추가해야 합니다. 다음과 같은 몇 가지 예외가 있습니다.

  • 단순(배열이 아닌) 할당 및 명령문과 같이 토큰화/세계화가 발생하지 않는 표현식에서 case. 다음은 안전합니다.

    • foo=*
    • foo=${bar}qux${quux}
    • foo=$(bar "${quux}")
    • case ${var} in

    그러나 이는 사실이 아닙니다(당신이 찾고 있는 것이 문자 그대로 별표 문자가 있는 단일 요소인 경우).

    • foo=( * )
  • 공백으로 구분된 문자열에서 토큰을 반복하는 등 특별히 토큰화를 수행하려는 경우(와일드카드 비활성화) 하지만 가능하다면 배열을 사용하세요.

답변2

주요 차이점은 인용된 버전이 쉘의 필드 분할에 영향을 받지 않는다는 것입니다.

큰따옴표를 사용하면 명령 확장 결과가 source명령에 대한 인수로 제공됩니다. 따옴표가 없으면 IFS기본적으로 공백, TAB 및 개행 문자가 포함된 값 에 따라 여러 인수로 구분됩니다 .

디렉터리 이름에 이러한 공백이 없으면 필드 분할이 발생하지 않습니다.

경험상 명령 대체 및 변수 확장에는 큰따옴표를 사용하는 것이 가장 좋습니다.

답변3

아마도 가장 중요한 차이점은 스크립트가 있는 디렉토리에 공백이 있는지 여부일 것입니다. 이 경우 첫 번째 줄(큰따옴표가 없는 줄)은 실패합니다. 이는 인용되지 않은 문자열을 bash "토큰화"한 결과입니다.

가상 결과 dirname ${BASH_SOURCE[0]}는 입니다 /home/j r/bin. 따옴표 없이 다음 줄을 살펴보세요.

source $(dirname ${BASH_SOURCE[0]})/script.sh

이 경우 bash는 다음 명령을 보게 됩니다:

source /home/j r/bin/script.sh

단어 분할 후 source명령은 스크립트 이름 /home/j과 스크립트 매개변수를 볼 수 있습니다 r/bin/script.sh. 해당 이름을 가진 스크립트가 없을 가능성이 높으며 bash는 오류 메시지를 반환합니다.

bash: /bin/j: No such file or directory

이제 큰따옴표를 사용하면 어떤 일이 발생하는지 생각해 보세요.

source "$(dirname ${BASH_SOURCE[0]})/script.sh"

이 경우 소스 명령은 이름이 지정된 스크립트를 찾아 /home/j r/bin/script.sh이를 얻으려고 시도합니다.

완전성을 위해 작은따옴표를 고려해 보겠습니다.

source '$(dirname ${BASH_SOURCE[0]})/script.sh'

이 경우 이전 두 가지와 달리 dirname실행되지 않습니다. 소스 명령은 리터럴 name 을 사용하여 명령을 얻으려고 시도합니다 $(dirname ${BASH_SOURCE[0]})/script.sh. 그러한 파일이 존재하지 않을 수도 있으며 bash는 오류 메시지를 발행할 것입니다.

bash가 큰따옴표로 묶인 문자열을 처리하는 방법은 다음 항목에 자세히 설명되어 있습니다 man bash.

  Enclosing characters in double quotes preserves the  literal  value  of
   all  characters  within the quotes, with the exception of $, `, \, and,
   when history expansion is enabled, !.  The characters $  and  `  retain
   their  special meaning within double quotes.  The backslash retains its
   special meaning only when followed by one of the following  characters:
   $,  `,  ", \, or <newline>.  A double quote may be quoted within double
   quotes by preceding it with a backslash.  If enabled, history expansion
   will  be  performed  unless an !  appearing in double quotes is escaped
   using a backslash.  The backslash preceding the !  is not removed.

관련 정보