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


658

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

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

var=10        # Declare variable

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

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

답변:


751

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

"${foo}bar"

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

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

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

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


106
{}라고도 중괄호 확장 . ${}변수 확장이라고합니다. 그들은 다른 일을합니다. 비 확장 비트를 제외하고는 귀하를 찬성했습니다.
스펜서 Rathbun

5
@NewUser " 배열 외에는 실제로 필요 하지 않습니다. "그렇지 않은 경우 스크립트 작성에 매우 유용한 PARAMETER EXPANSION에 중괄호가 필요합니다 . 약간의 매개 변수 확장으로 대체 할 수있는 많은 sed 및 awk 스크립트를 보았습니다.
SiegeX

10
@caffinatedmonkey $()는 명령을 실행하는 데 사용되며 , 이제 변수 를 사용하여 md5sum=$(md5sum foo.bin)출력 할 수 있습니다 . 또한 명시 적으로 작성하는 것이 좋습니다. md5sum foo.binmd5sum${md5sum}
L0j1k

11
@ L0j1k 명확성에 대해 말하면 $(), 서브 쉘 에서 명령 을 실행하는 것을 언급하는 것이 중요합니다 .
Adrian Günter

2
@karatedog ${1:-20}은 매개 변수 확장 형식입니다. 여기에는 주로 산술과 관련이 있다고 생각하는 데 숫자와 산술 연산자를 사용하기 때문에 분명하지 않지만 실제로 위치 매개 변수를 참조합니다.이 매개 변수 $1는 정의되지 않은 경우 기본값으로 대체됩니다 20(구문은 ${variable:-default_value}).
Aaron

126

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

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생각하는 것을하지 않습니다!


34

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

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

첫 줄을 이해할 수 없었습니다 dir=(*). 내가 아는 한 dir디렉토리 내용을 나열하는 내장 명령입니다 (와 동일 ls -C -b). 설명해 주시겠습니까?
Jarvis

1
쉘 프로그래밍에서 명령과 인수는 공백으로 구분해야합니다. 여기에 공백이없는 등호가 표시되는데 이는 변수 지정입니다. dir는 변수의 이름이며 괄호는 파일 이름 확장 *을 배열로 수집하는 데 사용됩니다 .
glenn jackman 2014 년

27

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

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

결과:

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

또는

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

결과:

This_is_a_string

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


11

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

전형적인 예 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의 답변은 이미 이것을 언급하지만 그의 예는 약간 추상적입니다)


5

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

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

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

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

보다:


1
It's good to be not over-cautious: 대부분의 사람들이 어떻게 생각하는지 궁금합니다. 가독성을 높이기 위해 항상 중괄호를 사용하여 필요할 때 잊어 버리거나 필요할 때만 사용하십시오.
Roger Dahl

1
프로그래머가 필요하지 않은 경우에도 컬리를 사용하게 만드는 것은 인식 부족이라고 생각합니다. 이 무지는 우발적 인 단어 분리 또는 글 로빙을 방지하기 위해 큰 따옴표를 사용하지 않는 다른 일반적인 실수와 유사합니다. 기본적으로 프로그래머는 Python 및 Ruby와 같은 다른 스크립팅 언어만큼 쉘 스크립팅에 대해 심각하지 않습니다.
codeforester

1
사실입니다. 내 애완 동물은 모든 사람들이 모든 변수가 쉘 스크립트에서 모두 대문자라고 생각하는 것 같습니다 :)
Roger Dahl

2

텍스트 조작에 대한 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

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


1
변수 주위에 중괄호 없이도 잘 작동합니다.
Armali

weel-known novel비트 를 고칠 수 있습니다 . 그럼에도 불구하고 공감했다.
gsl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.