[bash] 쉘 변수 주위에 중괄호가 필요할 때

쉘 스크립트에서 {}변수를 확장 할 때 언제 사용 합니까?

예를 들어 다음을 보았습니다.

var=10        # Declare variable

echo "${var}" # One use of the variable
echo "$var"   # Another use of the variable

중요한 차이점이 있습니까, 아니면 스타일입니까? 하나는 다른 것보다 선호됩니까?



답변

이 특정 예에서는 차이가 없습니다. 그러나,이 {}${}당신이 변수 확장하려는 경우에 유용 foo문자열을

"${foo}bar"

"$foobar"대신로 식별되는 변수를 확장하기 때문 입니다 foobar.

다음과 같은 경우에는 중괄호도 무조건 필요합니다.

  • 다음과 같이 배열 요소 확장 ${array[42]}
  • ${filename%.*}(확장자 제거) 에서와 같이 매개 변수 확장 조작 사용
  • 위치 매개 변수를 9 이상으로 확장 "$8 $9 ${10} ${11}"

잠재적으로 모호한 경우가 아니라 어디에서나이를 수행하는 것이 좋은 프로그래밍 관행으로 간주 될 있습니다. 이것은 $foo_$bar.jpg밑줄이 변수 이름의 일부가되는 것이 시각적으로 명확하지 않은 일관성과 놀라움을 피하기위한 것입니다.


답변

변수는없이 $또는없이 선언되고 할당됩니다 {}. 당신은 사용해야합니다

var=10

할당합니다. 변수를 읽으려면 (즉, ‘확장’변수) 반드시을 사용해야합니다 $.

$var      # use the variable
${var}    # same as above
${var}bar # expand var, and append "bar" too
$varbar   # same as ${varbar}, i.e expand a variable called varbar, if it exists.

이것은 때때로 혼란스러워했습니다. 다른 언어에서는 변수가 할당의 왼쪽에 있는지 또는 오른쪽에 있는지에 관계없이 동일한 방식으로 변수를 참조합니다. 그러나 쉘 스크립팅은 다르므로 $var=10생각하는 것을하지 않습니다!


답변

{}그룹화에 사용 합니다. 배열 요소를 역 참조하려면 중괄호가 필요합니다. 예:

dir=(*)           # store the contents of the directory into an array
echo "${dir[0]}"  # get the first entry.
echo "$dir[0]"    # incorrect


답변

중괄호 안에서 텍스트를 조작 할 수도 있습니다.

STRING="./folder/subfolder/file.txt"
echo ${STRING} ${STRING%/*/*}

결과:

./folder/subfolder/file.txt ./folder

또는

STRING="This is a string"
echo ${STRING// /_}

결과:

This_is_a_string

“정규 변수”는 필요하지 않습니다 … 디버깅에 더 도움이되고 스크립트를 읽는 것이 더 도움이됩니다.


답변

변수 이름의 끝은 일반적으로 공백 또는 줄 바꿈으로 표시됩니다. 그러나 변수 값을 인쇄 한 후 공백이나 줄 바꿈을 원하지 않으면 어떻게해야합니까? 중괄호는 쉘 인터프리터에게 변수 이름의 끝이 어디인지 알려줍니다.

전형적인 예 1)-후행 공백이없는 쉘 변수

TIME=10

# WRONG: no such variable called 'TIMEsecs'
echo "Time taken = $TIMEsecs"

# What we want is $TIME followed by "secs" with no whitespace between the two.
echo "Time taken = ${TIME}secs"

예제 2) 버전이 지정된 jar가있는 Java 클래스 경로

# WRONG - no such variable LATESTVERSION_src
CLASSPATH=hibernate-$LATESTVERSION_src.zip:hibernate_$LATEST_VERSION.jar

# RIGHT
CLASSPATH=hibernate-${LATESTVERSION}_src.zip:hibernate_$LATEST_VERSION.jar

(Fred의 답변은 이미 이것을 언급하지만 그의 예는 약간 추상적입니다)


답변

배열 요소에 액세스하고 괄호 확장을 수행하려면 항상 괄호가 필요합니다.

{}모호성에 대한 범위가없는 경우에도 지나치게주의하지 않고 쉘 변수 확장에 사용하는 것이 좋습니다 .

예를 들면 다음과 같습니다.

dir=log
prog=foo
path=/var/${dir}/${prog}      # excessive use of {}, not needed since / can't be a part of a shell variable name
logfile=${path}/${prog}.log   # same as above, . can't be a part of a shell variable name
path_copy=${path}             # {} is totally unnecessary
archive=${logfile}_arch       # {} is needed since _ can be a part of shell variable name

따라서 다음과 같이 세 줄을 작성하는 것이 좋습니다.

path=/var/$dir/$prog
logfile=$path/$prog.log
path_copy=$path

확실히 더 읽기 쉽습니다.

변수 이름은 숫자로 시작할 수 없으므로 셸은 확장이 뒤에 숫자가없는 한 {}번호가 매겨진 변수 (예 $1: $2등) 가 필요하지 않습니다 . 그것은 너무 미묘하고 {}그러한 맥락에서 명시 적으로 사용하게 합니다.

set app      # set $1 to app
fruit=$1le   # sets fruit to apple, but confusing
fruit=${1}le # sets fruit to apple, makes the intention clear

보다:


답변

텍스트 조작에 대한 SierraX와 Peter의 제안에 따라 중괄호 {}는 변수를 명령에 전달하는 데 사용됩니다.

잘 알려진 이탈리아 소설의 첫 줄이 들어 있는 sposi.txt 파일 이 있다고 가정 해 보겠습니다 .

> sposi="somewhere/myfolder/sposi.txt"
> cat $sposi

출력 : quel ramo del lago di como che volge a mezzogiorno

이제 두 개의 변수를 만듭니다 :

# Search the 2nd word found in the file that "sposi" variable points to
> word=$(cat $sposi | cut -d " " -f 2)

# This variable will replace the word
> new_word="filone"

이제 sposi.txt 파일 에서 단어 변수 내용을 new_word 중 하나로 대체하십시오.

> sed -i "s/${word}/${new_word}/g" $sposi
> cat $sposi

출력 : quel filone del lago di como che volge a mezzogiorno

“라모”라는 단어가 교체되었습니다.