$foo=*가 오류를 일으키지 않는 이유는 무엇입니까?

$foo=*가 오류를 일으키지 않는 이유는 무엇입니까?

쉘이 특정 유형의 문자를 확장한다는 것을 배웠습니다. 그렇기 때문에 글을 쓸 때:

$ echo *

디렉터리와 파일 목록을 얻었습니다. 다음과 같은 결과를 얻었다고 가정해 보겠습니다.

Applications Desktop Documents

이제 내가 글을 쓴다고 가정해보자.

$ foo=Applications Desktop Documents

나는 얻다:

-bash: Desktop: command not found

괜찮습니다만, 글을 쓸 때:

$ foo=*

그게 효과가 있는데, 왜요? 나는 *가 확장되어 위와 같은 오류를 발생시켜야 한다고 확신합니다.

글을 쓰는 동안

$ echo ${#foo}

*가 foo에 저장되었음을 보여주는 답변 1을 얻습니다.

작업에서 *가 확장되지 않는 이유는 무엇입니까? 쓰다보니 늘어나네요

$ echo ${foo}

감사해요

답변1

변수 할당 중에는 경로 이름 확장이 발생하지 않습니다. 다음은 bash 맨페이지에서 발췌한 내용입니다.

값이 지정되지 않으면 변수에 빈 문자열이 할당됩니다. 모든 값은 물결표 확장, 매개변수 및 변수 확장, 명령 대체, 산술 확장, 따옴표 제거를 거칩니다(아래 확장 참조). 변수에 정수 속성 세트가 있는 경우 $((...)) 확장이 사용되지 않더라도 값은 산술 표현식으로 평가됩니다(아래 산술 확장 참조). 아래 특수 매개변수에 설명된 대로 "$@"을 제외하고 단어 분리는 수행되지 않습니다. 경로 이름 확장은 수행되지 않습니다.

할당을 수행하면 foo=*foo 변수에 리터럴이 포함됩니다 *. 나중에 변수(따옴표 없이)를 사용하면 매개변수가 먼저 리터럴로 확장된 *다음 경로 이름 확장이 발생합니다. *매개변수 확장을 인용하여 리터럴이 포함되어 있는지 확인할 수 있습니다 .

$ foo=*
$ echo "$foo"
*

배열을 할당할 때와 같이 bash에는 이 규칙에 대한 몇 가지 예외가 있습니다.

$ foo=(*)

위의 예에서 경로 이름 확장은 즉시 발생하며 배열에는 glob과 일치하는 파일 목록이 포함됩니다.

답변2

쉘이 와일드카드를 glob으로 확장할 수 없는 경우 문자 그대로 처리됩니다.

$ cd scratch
$ rm *
$ foo=*
$ echo $foo
*
$ echo "$foo"
*
$ touch file
$ echo $foo
file
$ echo "$foo"
*

관련 정보