제목의 말씀 : 그것은의 변수 캡슐화을 의미 하는가 무엇을 {}
, ""
또는 "{}
? “를 나는 이것에 대해 온라인 어떤 설명을 찾을 수 없어 – 나는 상징을 사용하는 것을 제외하고는, 그들에게 참조 할 수되지 않은 아무것도 생산하지 않습니다.
예를 들면 다음과 같습니다.
declare -a groups
groups+=("CN=exampleexample,OU=exampleexample,OU=exampleexample,DC=example,DC=com")
groups+=("CN=example example,OU=example example,OU=example example,DC=example,DC=com")
이:
for group in "${groups[@]}"; do
echo $group
done
이것과는 많이 다르다는 것을 증명합니다 :
for group in $groups; do
echo $group
done
이:
for group in ${groups}; do
echo $group
done
첫 번째 것만으로 원하는 것을 달성합니다. 배열의 각 요소를 반복합니다. 나는의 차이점에 정말 명확하지 않다 $groups
, "$groups"
, ${groups}
와 "${groups}"
. 누구나 설명 할 수 있다면 고맙겠습니다.
추가 질문으로-이 캡슐화를 참조하는 허용되는 방법을 아는 사람이 있습니까?
답변
괄호 ( $var
대 ${var}
)
대부분의 경우 $var
와 ${var}
동일합니다 :
var=foo
echo $var
# foo
echo ${var}
# foo
중괄호는 표현식의 모호성을 해결하는 데만 필요합니다.
var=foo
echo $varbar
# Prints nothing because there is no variable 'varbar'
echo ${var}bar
# foobar
따옴표 ( $var
대 "$var"
대 "${var}"
)
변수 주위에 큰 따옴표를 추가하면 공백이 포함되어 있어도 쉘에 단일 단어로 취급하도록 지시합니다.
var="foo bar"
for i in "$var"; do # Expands to 'for i in "foo bar"; do...'
echo $i # so only runs the loop once
done
# foo bar
이 동작을 다음과 대조하십시오.
var="foo bar"
for i in $var; do # Expands to 'for i in foo bar; do...'
echo $i # so runs the loop twice, once for each argument
done
# foo
# bar
와 마찬가지로 $var
대 ${var}
, 중괄호은 예를 들어, 동음이 필요하다 :
var="foo bar"
for i in "$varbar"; do # Expands to 'for i in ""; do...' since there is no
echo $i # variable named 'varbar', so loop runs once and
done # prints nothing (actually "")
var="foo bar"
for i in "${var}bar"; do # Expands to 'for i in "foo barbar"; do...'
echo $i # so runs the loop once
done
# foo barbar
참고 "${var}bar"
두 번째 예에서는 상기도 기록 할 수 "${var}"bar
있으며,이 경우에 당신은 즉, 더 이상 괄호가 필요하지 않습니다 "$var"bar
. 그러나 문자열에 따옴표가 많으면 이러한 대체 양식을 읽기가 어려워 유지 관리가 어려울 수 있습니다. 이 페이지 는 Bash 인용에 대한 좋은 소개를 제공합니다.
배열 ( $var
대 $var[@]
vs. ${var[@]}
)
이제 배열을 위해. bash 매뉴얼 에 따르면 :
첨자가없는 배열 변수를 참조하는 것은 첨자가 0 인 배열을 참조하는 것과 같습니다.
다시 말해,로 색인을 제공하지 않으면 []
배열의 첫 번째 요소를 얻게됩니다.
foo=(a b c)
echo $foo
# a
정확히 같은
foo=(a b c)
echo ${foo}
# a
배열의 모든 요소를 가져 오려면 @
인덱스 로 사용해야 합니다 (예 🙂 ${foo[@]}
. 괄호는 배열이 없으면 셸이 $foo
부분을 먼저 확장 하여 배열의 첫 번째 요소와 리터럴을 제공하므로 배열에 필요합니다 [@]
.
foo=(a b c)
echo ${foo[@]}
# a b c
echo $foo[@]
# a[@]
이 페이지 는 Bash의 배열에 대한 좋은 소개입니다.
재 방문한 따옴표 ( ${foo[@]}
vs. "${foo[@]}"
)
당신은 이것에 대해 묻지 않았지만 알기에 좋은 미묘한 차이입니다. 배열의 요소에 공백이 포함될 수있는 경우 각 요소가 별도의 “단어”로 처리되도록 큰 따옴표를 사용해야합니다.
foo=("the first" "the second")
for i in "${foo[@]}"; do # Expands to 'for i in "the first" "the second"; do...'
echo $i # so the loop runs twice
done
# the first
# the second
이것을 큰 따옴표없이 동작과 대조하십시오 :
foo=("the first" "the second")
for i in ${foo[@]}; do # Expands to 'for i in the first the second; do...'
echo $i # so the loop runs four times!
done
# the
# first
# the
# second
답변
TL; DR
제공하는 모든 예제는 Bash Shell Expansions의 변형입니다 . 확장은 특정 순서로 발생하며 일부는 특정 사용 사례가 있습니다.
토큰 구분 기호로 중괄호
이 ${var}
구문은 모호한 토큰을 구분하는 데 주로 사용됩니다. 예를 들어 다음을 고려하십시오.
$ var1=foo; var2=bar; var12=12
$ echo $var12
12
$ echo ${var1}2
foo2
어레이 확장 중괄호
괄호는 배열 의 요소에 액세스하고 다른 특수 확장에 필요 합니다. 예를 들면 다음과 같습니다.
$ foo=(1 2 3)
# Returns first element only.
$ echo $foo
1
# Returns all array elements.
$ echo ${foo[*]}
1 2 3
# Returns number of elements in array.
$ echo ${#foo[*]}
3
토큰 화
나머지 질문의 대부분은 인용 및 쉘이 입력을 토큰 화하는 방법과 관련이 있습니다. 다음 예제에서 쉘이 단어 분리 를 수행하는 방법의 차이점을 고려하십시오 .
$ var1=foo; var2=bar; count_params () { echo $#; }
# Variables are interpolated into a single string.
$ count_params "$var1 $var2"
1
# Each variable is quoted separately, created two arguments.
$ count_params "$var1" "$var2"
2
@기호는 다르게 인용과 상호 작용한다 *. 구체적으로 특별히:
$@
“[e] xp로 시작하고 위치 매개 변수는 1부터 시작합니다. 큰 따옴표 내에서 확장이 발생하면 각 매개 변수는 별도의 단어로 확장됩니다.”- 배열에서, “[i] f 단어는 큰 따옴표로
${name[*]}
묶어 각 배열 구성원의 값을 IFS 변수의 첫 문자로 분리하여 단일 단어로${name[@]}
확장하고 이름의 각 요소를 별도의 단어로 확장합니다.”
다음과 같이 실제로 작동하는 것을 볼 수 있습니다.
$ count_params () { echo $#; }
$ set -- foo bar baz
$ count_params "$@"
3
$ count_params "$*"
1
변수가 공백이나 특수 문자가있는 값을 참조하여 쉘이 의도 한 방식으로 단어를 분리하지 못하게 할 때 인용 확장을 사용하는 것이 중요합니다. Bash에서 인용이 작동하는 방법에 대한 자세한 내용은 인용 을 참조하십시오 .
답변
배열과 간단한 변수를 구별해야합니다. 예제에서는 배열을 사용하고 있습니다.
일반 변수의 경우 :
$var
와${var}
정확히 동일합니다."$var"
와"${var}"
정확히 동일합니다.
그러나 두 경우 모두 100 % 동일하지는 않습니다. 아래 출력을 고려하십시오.
$ var=" abc def "
$ printf "X%sX\n" $var
XabcX
XdefX
$ printf "X%sX\n" "${var}"
X abc def X
$
변수 주위에 큰 따옴표가 없으면 내부 간격이 없어지고 확장은 printf
명령 에 대한 두 개의 인수로 처리됩니다 . 변수 주위에 큰 따옴표를 사용하면 내부 간격이 유지되고 확장은 printf
명령 에 대한 하나의 인수로 처리됩니다 .
배열을 사용하면 규칙이 비슷하고 다릅니다.
- 경우
groups
참조하는 배열이다$groups
또는${groups}
참조 동등하다${groups[0]}
어레이의 영차 소자. - 참조
"${groups[@]}"
는 참조 와 유사합니다"$@"
. 배열의 개별 요소에 간격을 유지하고 배열의 요소 당 하나의 값으로 값 목록을 반환합니다. ${groups[@]}
큰 따옴표가없는 참조 는 간격을 유지하지 않으며 일부 요소에 공백이 있으면 배열에있는 요소보다 많은 값을 도입 할 수 있습니다.
예를 들면 다음과 같습니다.
$ groups=("abc def" " pqr xyz ")
$ printf "X%sX\n" ${groups[@]}
XabcX
XdefX
XpqrX
XxyzX
$ printf "X%sX\n" "${groups[@]}"
Xabc defX
X pqr xyz X
$ printf "X%sX\n" $groups
XabcX
XdefX
$ printf "X%sX\n" "$groups"
Xabc defX
$
*
대신에 사용하면 @
미묘하게 다른 결과가 나타납니다.
스크립트 에서 인수를 반복하는 방법을bash
참조하십시오 .
답변
아래의 첫 번째 단락의 두 번째 문장 매개 변수 확장 에는 man bash
말한다
확장 될 매개 변수 이름 또는 기호는 중괄호로 묶을 수 있으며, 선택 사항이지만 변수가 이름 바로 뒤에 오는 문자에서 확장되도록 변수를 보호하는 역할을합니다.
이름은 단순히 중괄호 이며 주요 목적은 이름의 시작과 끝을 명확히하는 것입니다.
foo='bar'
echo "$foobar"
# nothing
echo "${foo}bar"
barbar
더 자세히 읽으면,
매개 변수가 두 자리 이상의 위치 매개 변수 인 경우 중괄호가 필요합니다…
테스트하자 :
$ set -- {0..100}
$ echo $22
12
$ echo ${22}
20
허. 산뜻한. 나는 이것을 작성하기 전에 솔직히 몰랐다 (이전에 위치 매개 변수가 9 개 이상 없었습니다.)
물론 다음과 같은 강력한 매개 변수 확장 기능을 수행하려면 중괄호가 필요합니다.
${parameter:-word}
${parameter:=word}
${parameter:?word}
… [read the section for more]
뿐만 아니라 배열 확장.
답변
위에서 다루지 않은 관련 사례. 빈 변수를 인용하면의 내용이 바뀌는 것 같습니다 test -n
. 이것은에 대한 info
텍스트 로 구체적으로 coreutils
설명되어 있지만 실제로 설명되어 있지는 않습니다.
16.3.4 String tests
-------------------
These options test string characteristics. You may need to quote
STRING arguments for the shell. For example:
test -n "$V"
The quotes here prevent the wrong arguments from being passed to
`test' if `$V' is empty or contains special characters.
자세한 설명을 듣고 싶습니다. 내 시험이를 확인하고, 지금 피하기 위해, 모든 문자열 테스트를 위해 내 변수를 인용하고 있습니다 -z
와 -n
같은 결과를 반환합니다.
$ unset a
$ if [ -z $a ]; then echo unset; else echo set; fi
unset
$ if [ -n $a ]; then echo set; else echo unset; fi
set # highly unexpected!
$ unset a
$ if [ -z "$a" ]; then echo unset; else echo set; fi
unset
$ if [ -n "$a" ]; then echo set; else echo unset; fi
unset # much better
답변
글쎄, 변수 캡슐화는 다음과 같은 작업을하는 데 도움이된다는 것을 알고 있습니다.
${groups%example}
값을 반환하기 전에 변수로 무언가를하고 싶은 구문.
코드가 보이면 모든 마법이
${groups[@]}
마법은 거기에 쓸 수 없기 때문에 거기에 있습니다. $groups[@]
{}
특수 문자 []
및 을 사용하려고하므로 변수를 안에 넣습니다 @
. : 당신의 이름 또는 당신의 변수를 호출 할 수 없습니다 @
또는 something[]
이 다른 운영 및 이름에 예약 된 문자 때문이다.