할당 전에 물결표 접두사는 확장되지만 중괄호는 확장되지 않는 이유는 무엇입니까?

할당 전에 물결표 접두사는 확장되지만 중괄호는 확장되지 않는 이유는 무엇입니까?

tl;디렉토리

Bash에서는 물결표 확장 전에 중괄호 확장이 발생합니다. 그러나 물결표 접두사는 변수 할당 전에 확장되는 것처럼 보이지만 중괄호 확장은 그렇지 않습니다. 왜?

세부정보 및 예시

지원 확장Bash에서는 다음에서 발생한 것으로 기록됩니다.물결표 확장:

중괄호 확장은 다른 확장보다 먼저 수행됩니다.

내가 이해한 바로는 다음 예와 같이 물결표 확장이 변수 할당 전에 발생합니다.

# UNQUOTED TILDE PREFIX, TILDE EXPANSION EXPECTED
tilde=~
echo "$tilde"
# /Users/DeNovo
[[ $tilde == "$HOME" ]] && echo "literal match"
# literal match

# QUOTED TILDE PREFIX, TILDE EXPANSION DOES NOT OCCUR
lit_tilde='~'
echo "$lit_tilde"
# ~
# UNQUOTED TILDE PREFIX PRODUCED AND EVALUATED, TILDE EXPANSION OCCURS
# AS EXPECTED
eval echo "$lit_tilde"
# /Users/DeNovo
[[ $lit_tilde == "~" ]] && echo "literal match"
# literal match

이러한 예는 오른쪽 피연산자가 left=right왼쪽 피연산자에 값으로 바인딩되기 전에 물결표 확장을 겪는다는 것을 나타내는 것 같습니다.

그러나 중괄호 확장은 변수 할당 전에 발생하지 않으며 리터럴 물결표를 변수에 바인딩하는 것과 유사하게 동작합니다(확장된 특수 문자/접두사 대비).

# UNQUOTED BRACE, BUT NO EXPANSION. BRACE LITERAL IS PRESERVED
brace={a..c}
echo "$brace"
# {a..c}
[[ $brace = "a b c" ]] || echo "doesn't match"
# doesn't match
[[ $brace = "{a..c}" ]] && echo "literal match"
# literal match

# SIMILAR TO THE LITERAL TILDE, EVALUATING THE VARIABLE VALUE 
# RESULTS IN BRACE EXPANSION
eval echo "$brace"
# a b c

두 확장을 단일 예제로 결합하면 물결표 확장이 발생하지만 중괄호 확장은 발생하지 않는 것을 볼 수 있습니다.

combined=~/dir_{a..c}
echo "$combined"
# /Users/DeNovo/dir_{a..c}

중괄호는 할당 중에 내부 물결표가 확장되는 것을 방지합니다.

internal_tilde={~,~+}/new_dir
echo "$internal_tilde"
# {~,~+}/new_dir

# vs the same output, not in a variable
echo {~,~+}/new_dir
/Users/DeNovo/new_dir /Your/Working/Directory/new_dir

명확히 하기 위해 중괄호 확장 결과를 포함하는 변수를 얻는 방법을 묻는 것이 아니라 물결표 확장 이전에 발생했음에도 불구하고 변수 할당 전에 중괄호 확장이 발생하지 않는 이유를 묻는 것입니다. 원하는 동작을 얻는 방법에는 여러 가지가 있습니다. 이것은:

# PROCESS SUBSTITUTION GIVES THE DESIRED BEHAVIOR
brace_exp="$(echo {a..c})"
echo "$brace_exp"
a b c
[[ $brace_exp = "a b c" ]] && echo "literal match"
# literal match

다시 말하지만, 물결표 확장은 왜 변수 할당 전에 발생하지만 중괄호 확장(물결표 확장 전에 발생해야 함)은 변수 할당 전에 발생하지 않습니다. 아마도 그 임무는 내가 모르는 어떤 면에서 특별할 것 같습니다.

답변1

테스트에서는 {a..c}확장이 변수 할당의 일부이고 처리되기 때문에 확장이 없습니다.각기:

  1. 파서에 의해 변수 할당으로 표시된 단어(명령 이름 앞의 단어)와 리디렉션은 나중에 처리하기 위해 저장됩니다.
  2. 변수 할당이나 리디렉션이 아닌 단어는 확장됩니다.쉘 확장). 확장 후 남은 단어가 있는 경우 첫 번째 단어는 명령 이름으로 처리되고 나머지 단어는 인수로 처리됩니다.

할당된 값은 중괄호로 확장되지 않습니다.

  1. 각 변수 할당에서 " " 뒤에 오는 텍스트는 =변수에 할당되기 전에 물결표 확장, 매개변수 확장, 명령 대체, 산술 확장 및 따옴표 제거를 거칩니다.

답변2

@StephenKitt의 답변은 이 동작이 예상됨을 나타내는 관련 문서(+1)를 가리킵니다(왜 물결표 접두사는 할당 전에 확장되지만 중괄호는 확장되지 않습니까? 그것이 정의된 방식이기 때문입니다).

답변: 교정기 확장이 특별한 이유 중 하나, 그것이 무엇인지 살펴보겠습니다.아니요변수를 할당할 때 발생합니다.

  • 버팀대 확장
  • 단어 분할(파서가 줄을 분할하지만 해당 단어 내에서 확장된 결과는 분할되지 않음)
  • 파일 이름 확장자

확장된 단어 수를 변경할 수 있는 작업은 다음과 같습니다.

쉘 확장:

중괄호 확장, 토큰화 및 파일 이름 확장만 확장된 단어 수를 변경할 수 있습니다.

예제의 경우 변수는 배열이 아닌 문자열이며 하나의 단어만 포함해야 합니다.

지원 확장하다더 복잡한 예를 사용하면 다음과 같이 배열이 할당될 때 발생합니다 brace=({a..c}).

internal_tilde=({~,~+}/new_dir)
echo "${internal_tilde[@]}"
# /Users/DeNovo/new_dir /Your/Working/Directory/new_dir

그러므로 나는 이 디자인이 (역사적으로 이상한 것이 아니라) 의미가 있다고 생각합니다. 물결표 확장은 단어 수를 변경하지 않습니다. 중괄호 확장이 수행됩니다. 변수에 여러 단어가 포함되도록 하려면 이를 위해 특별히 설계된 데이터 구조를 사용하세요.

관련 정보