{a, b, c}는 bash에서 언제 확장됩니까?


13

포함하는 bash 스크립트

for i in {a,b}-{1,2}; do
  echo $i;
done

인쇄물

a-1
a-2
b-1
b-2

실행될 때. 이것이 {a,b}구조가 확장 됨에 따라 예상 한 것 입니다.

그러나 (또 다른) 스크립트에

v={a,b}-{1,2}
echo $v

그것은 인쇄

{a,b}-{1,2}

내가 기대 한 것이 아닙니다. 나는 그것을 인쇄 할 것으로 예상했다 a-1 a-2 b-1 b-2. 분명히 {a,b}구성은 확장되지 않습니다.

그렇게 확장시킬 수 있습니다

v=$(echo {a,b}-{1,2})

이러한 관찰을 바탕으로 두 가지 질문이 있습니다. 1) {a,b}구조 가 언제 확장됩니까? 2) $(echo {a,b}-{1,2})필요할 때 확장을 시작하는 선호되는 방법입니까?


1
이것은 최소한 배열 변수를 simple로 만들 수 없다는 사실과 일치합니다 =. 예를 들어 v=a-1 a-2작동하지 않습니다.
grochmal

@grochmal-스칼라 값을 할당하기 때문입니다. v=a-1 a-2의미 assign 'a-1' to variable v and run 'a-2' v=(a-1 a-2)는 배열을 variable에 할당합니다 v. v+=(b-1 b-2)그것에 덧붙입니다.
cas

답변:


15

배쉬 설명서는 말한다 :

SIMPLE COMMAND EXPANSION
When a simple command is executed, the shell performs the following
expansions, assignments, and redirections, from left to right.
[...]
4. The  text  after the = in each variable assignment undergoes tilde
   expansion, parameter expansion, command substitution, arithmetic
   expansion, and quote removal before being assigned to the variable.

중괄호 확장이 목록에 없으므로 할당에 대해 수행되지 않습니다 v={a,b}-{1,2}. @Wildcard에서 언급했듯이 간단한 확장 v=a-1 v=b-1 ...은 어쨌든 의미가 없습니다.

또한를 실행할 때 echo $v다음이 적용됩니다.

EXPANSION
Expansion is performed on the command line after it has been split
into words. [...]

The order of expansions is: brace expansion; tilde expansion, 
parameter and variable expansion, arithmetic expansion, and command
substitution (done in a left-to-right fashion); word splitting; and
pathname expansion.

변수 확장 전에 가새 확장이 발생하므로 할당 된 가새 $v가 확장되지 않습니다.

그러나 다음과 같은 작업을 수행 할 수 있습니다.

$ var_this=foo var_that=bar
$ echo $var_{this,that}
foo bar

확장 할 $(echo ...)문자열에 공백이 없으면 확장하면 작동하므로 단어 분리 문제가 발생하지 않습니다. 가능하면 배열 변수를 사용하는 것이 더 좋습니다.

예를 들어, 확장을 배열에 저장하고 확장 된 값으로 일부 명령을 실행하십시오.

$ v=( {a,b}-{1,2} )
$ some_command "${v[@]}"

5

흥미로운 점입니다. 다음에서 발췌 한 내용이 도움이 될 수 있습니다 man bash.

변수는 형식의 문에 할당 할 수있다

      이름 = [ value ]

경우 값이 주어지지, 변수는 널 (null) 문자열을 할당됩니다. 모든 은 물결 확장, 매개 변수 및 변수 확장, 명령 대체, 산술 확장 및 따옴표 제거를 수행합니다 (아래 확장 참조).

중괄호 확장은 목록에 언급되어 있지 않습니다.

그러나 이것은 여전히 ​​의문을 남깁니다. 즉, 쉘은 이것이 변수 할당이므로 중괄호 확장이 적용되지 않음을 어떻게 알 수 있습니까? 보다 정확하게 말하면 구문 분석 시퀀스는 어디에 중괄호 확장을 처리하기 전에 변수 할당을 식별하기 위해 정의되도록 쉘을 정의하고 체계화합니까? (이것은 분명히 bash작동 하는 방식이지만 이것을 설명하는 정확한 문서 라인을 찾지 못했습니다.)


1
어쩌면 이것 ? "2. 가변적 인 할당이나 방향 전환이 아닌 단어가 확장됩니다 (쉘 확장 참조).
Jeff Schaller

@JeffSchaller, 맞습니다. 실제로이 질문은 "SIMPLE COMMAND EXPANSION"( LESS=+/SIMPLE man bash) 섹션을 읽으면 가장 잘 대답 할 수 있습니다.
와일드 카드

0

내 지식에 따르면 {a, b, c}는 mkdir ~ / {a, b, c} 명령과 함께 직접 반향되거나 사용될 때 확장되지만 변수로 설정되면 이전에 평가해야합니다 그것을 반향하거나 인수로 사용하십시오!

u@h:~$ echo {a,b}-{1,2}
a-1 a-2 b-1 b-2
u@h:~$ v={a,b}-{1,2}
u@h:~$ echo $v
{a,b}-{1,2}
u@h:~$ eval echo $v
a-1 a-2 b-1 b-2

알파벳 순서 [az]에서 "a"뒤에 "b"가 있고, [0-9]에 순서대로 "1"뒤에 "2"가 있기 때문에 : 쉼표 "insted"라는 이중 마침표 ".."를 사용할 수 있습니다. "

u@h:~$ echo {a..b}-{1..2}
a-1 a-2 b-1 b-2
u@h:~$ v={a..b}-{1..2}
u@h:~$ echo $v
{a..b}-{1..2}
u@h:~$ eval echo $v
a-1 a-2 b-1 b-2

1
문제는 리터럴 문자열 "a-1 a-2 b-1 b-2"로 설정v 되지 않은 이유 입니다. 또는 적어도 명령을 입력하면 오류가 발생하지 않는 이유는 다음과 같습니다 (변수 할당이 확장 될 것으로 예상합니다). 좋은 질문입니다. 이것은 실제로 대답하지 않습니다. v=a-1 v=a-2 v=b-1 v=b-2
와일드 카드

@SatoKatsura, "와일드 카드 확장"이란 무엇입니까? 매개 변수 확장, 경로 이름 확장 및 중괄호 확장이 있습니다. 모두 참조 할 수 있고 모두 다릅니다. 아니면 단어 나누기를 의미 했습니까?
와일드 카드

0

bash에서 변수에 할당해도 표현식이 확장되지 않습니다.

이 작은 스크립트의 경우 x는 "*"다음을 확장하지 않고 포함합니다 "*".

#!/bin/bash
x=*
echo "$x"

그러나 일부 값은 확장됩니다. ilkkachu의 좋은 답변.

식이 평가 될 때 확장됩니다.

이처럼 :

x=$(echo *)        # <-- evaluation of "*"
echo "$x"

또는 이렇게 :

x=*
echo $x            # <-- evaluation of $x

또는 이렇게 :

x=*
eval echo "$x"     # <-- evaluation of `echo *`

트리거링 $()은 상당히 일반적이며 선호하는 것보다는 eval좋지만, 실제로 변수가 명령에 사용될 때까지 평가를 전혀 트리거하지 않는 것이 가장 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.