programing

Bash 셸에서 ${var}, "$var" 및 "${var}"의 차이점은 무엇입니까?

starjava 2023. 5. 27. 09:16
반응형

Bash 셸에서 ${var}, "$var" 및 "${var}"의 차이점은 무엇입니까?

제목에서 말하는 것: 변수를 캡슐화하는 것은 무엇을 의미합니까?{},""또는"{}저는 온라인에서 이것에 대한 설명을 찾을 수 없었습니다. 저는 아무것도 산출하지 않는 기호를 사용하는 것 외에는 그것들을 참조할 수 없었습니다.

다음은 예입니다.

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[@]대 대${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의 어레이에 대한 좋은 소개입니다.

방문한 인용문 (다시방문인문용한(문인용▁quotes▁revis다)${foo[@]}대 대"${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 Expansion의 변형입니다.확장은 특정 순서로 이루어지며, 일부는 특정 사용 사례가 있습니다.

토큰 구분 기호로 중괄호 사용

${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

기호는 와 다르게 따옴표와 상호 작용합니다. 구체적으로 다음과 같습니다.

  1. $@"[e]위치 매개 변수를 하나부터 시작하여 확장합니다.큰따옴표 안에서 확장이 발생하면 각 매개 변수는 별도의 단어로 확장됩니다."
  2. ", " 배로단만이묶로표면인다옴따중가어열약,면묶▁in다인▁"만▁"[약로표,옴-,▁array▁an▁the,"${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]}배열의 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
$

용사를 합니다.*@미묘하게 다른 결과로 이어집니다.

스크립트에서 인수를 반복하는 방법을 참조하십시오.

파라미터 확장 아래 첫 번째 단락의 두 번째 문장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[]다른 작업 및 이름에 대해 예약된 문자이기 때문입니다.

$var그리고.${var} 동한경우일면.var변수의 이름입니다.

매개 변수가 숫자가 두 개 이상인 위치 매개 변수이거나 매개 변수 뒤에 이름의 일부로 해석되지 않는 문자가 있을 때 중괄호가 필요합니다.

따라서,"$var"그리고."${var}"똑같습니다.

하만지,$var그리고."$var"다릅니다.Bash가 다음에 대해 워드 분할을 수행합니다.$var하지만 때문은 아닙니다."$var".

셸은 단어 분할을 위해 큰따옴표 내에서 발생하지 않은 매개 변수 확장, 명령 대체 및 산술 확장 결과를 검색합니다.

참고: 변수 할당에서 단어 분할이 수행되지 않습니다. https://www.gnu.org/software/bash/manual/html_node/Shell-Parameters.html

폼의 문으로 변수를 할당할 수 있습니다.

name=[value]

값을 지정하지 않으면 변수에 null 문자열이 할당됩니다.모든 값은 타일 확장, 파라미터 및 변수 확장, 명령 대체, 산술 확장 및 따옴표 제거를 수행합니다(쉘 파라미터 확장 참조).변수에 정수 속성이 설정되어 있으면 $(…) 확장을 사용하지 않더라도 값이 산술 식으로 평가됩니다(산술 확장 참조).단어 분할 및 파일 이름 확장이 수행되지 않습니다.

언급URL : https://stackoverflow.com/questions/18135451/what-is-the-difference-between-var-var-and-var-in-the-bash-shell

반응형