a="$@"에 대한 예상치 못한 결과

a="$@"에 대한 예상치 못한 결과

나는 이 상황과 싸우고 있습니다:

$ set -- 1 2 3
$ a="$@"
$ echo "$a"
1 2 3

제가 놀랐던 점은 과제 자체였습니다.

man bash확장 프로그램 에 대해 "$@"다음과 같이 말합니다 .

큰따옴표 내에서 확장이 발생하면 각 인수가 별도의 단어로 확장됩니다.

따라서 이는 다음과 유사해야 합니다.

b="1" "2" "3"
bash: 2: command not found

나는 이것이 "$*"확장의 목적이라고 생각합니다.

큰따옴표 내에서 확장이 발생하면 IFS 특수 변수의 첫 번째 문자로 구분된 각 인수의 값을 사용하여 단일 단어로 확장됩니다. 즉, "$*"는 "$1c$2c..."와 동일합니다. 여기서 c는 IFS 변수 값의 첫 번째 문자입니다. IFS가 설정되지 않은 경우 매개변수는 공백으로 구분됩니다. IFS가 비어 있으면 매개변수를 연결할 때 구분 기호가 삽입되지 않습니다.

따라서 다음이 정확해야 합니다.

$ set -- 1 2 3
$ a="$*"
$ echo "$a"
1 2 3

그렇다면 "$@"수익률은 왜 똑같을까요? 이 시점에서는 달라야 합니다. 이것이 Bash 문제입니까 아니면 제 오해입니까?

주택 검사이것을 다음과 같이 감지SC2124. 트리거링의 예를 제공할 수도 있습니다.SC2145.

관찰됨:

GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 GNU/Linux

답변1

내가 아는 한,POSIX $@정의되지 않은 할당, Bash의 문서를 제외하고는 실제로 버그가 아닙니다. $@이는 두 가지 상황으로 정의됩니다.

  • 필드 분할이 수행되는 컨텍스트에서 확장이 발생하는 경우...
  • 큰따옴표 내에서 확장이 발생하는 경우 [...]가 필드 분할을 수행하지 않는 한 동작은 지정되지 않습니다. [...] (*)

하지만,

다른 모든 경우에는 확장 결과는 다음과 같습니다.명시되지 않은.

필드 분할은 큰따옴표 없이도 할당에서 발생하지 않으므로 정의되지 않습니다.


a="$@"이제 여러 단어로 확장하는 것과 같은 방식으로 작동한다고 가정합니다. a="$*"여기서는 실제로 의미가 없습니다. 일반 변수에 여러 단어를 다른 엔터티로 할당할 수 없으며, 한 단어를 할당하고 나머지 단어를 명령 인수로 사용하면 혼란스럽고 오류가 발생하기 쉽습니다.

"$@"이 shellcheck 페이지에 언급된 대로 할당 동작은 쉘마다 다릅니다. Bash와 ksh는 위치 인수를 공백으로 연결하고, zsh와 dash는 위치 인수를 첫 번째 문자로 연결합니다 IFS(정확히 "$*"이와 같습니다).

$ bash -c 'set -- x y z; IFS=.; a="$@"; printf "<%s>\n" "$a"'
<x y z>
$ ksh93 -c 'set -- x y z; IFS=.; a="$@"; printf "<%s>\n" "$a"'
<x y z>
$ zsh -c 'set -- x y z; IFS=.; a="$@"; printf "<%s>\n" "$a"'
<x.y.z>
$ dash -c 'set -- x y z; IFS=.; a="$@"; printf "<%s>\n" "$a"'
<x.y.z>

a="$*"단일 문자열로 연결하려는 경우 또는 원하는 내용을 명시적으로 작성하려는 경우 이 방법을 사용하는 것이 가장 좋습니다.

(*또는 확장과 관련된 기타 경우 ${parameter:-word})

관련 정보