포함하는 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})
필요할 때 확장을 시작하는 선호되는 방법입니까?
답변
배쉬 설명서는 말한다 :
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[@]}"
답변
흥미로운 점입니다. 다음에서 발췌 한 내용이 도움이 될 수 있습니다 man bash
.
변수는 형식의 문에 할당 할 수있다
이름 = [ value ]
경우 값이 주어지지, 변수는 널 (null) 문자열을 할당됩니다. 모든 값 은 물결 확장, 매개 변수 및 변수 확장, 명령 대체, 산술 확장 및 따옴표 제거를 수행합니다 (아래 확장 참조).
중괄호 확장은 목록에 언급되어 있지 않습니다.
그러나 이것은 여전히 의문을 남깁니다. 즉, 쉘은 이것이 변수 할당이므로 중괄호 확장이 적용되지 않음을 어떻게 알 수 있습니까? 보다 정확하게 말하면 구문 분석 시퀀스는 어디에 중괄호 확장을 처리하기 전에 변수 할당을 식별하기 위해 정의되도록 쉘을 정의하고 체계화합니까? (이것은 분명히 bash
작동 하는 방식이지만 이것을 설명하는 정확한 문서 라인을 찾지 못했습니다.)
답변
내 지식에 따르면 {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
답변
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
좋지만, 실제로 변수가 명령에 사용될 때까지 평가를 전혀 트리거하지 않는 것이 가장 좋습니다.