변수인 parameter의 값이란 뜻으로서, $parameter라고 한 것과 같습니다. 어떤 문맥에서는 ${parameter}라고 확실히 써 줘야 동작하는 수도 있습니다.
문자열 변수들을 연결할 때 쓰일 수 있습니다.
your_id=${USER}-on-${HOSTNAME} echo "$your_id" # echo "Old \$PATH = $PATH" PATH=${PATH}:/opt/bin # 스크립트가 도는 동안 $PATH 에 /opt/bin 을 추가. echo "New \$PATH = $PATH" |
매개변수가 세트되지 않았다면 default를 사용합니다.
echo ${username-`whoami`} # $username이 여전히 세트되어 있지 않다면 `whoami`의 결과를 에코. |
참고: 이렇게 하면 ${parameter:-default}라고 하는 것과 거의 비슷하지만 :이 있을 때는 매개변수가 선언만 되어 값이 널일 경우에도 기본값을 적용시킵니다.
#!/bin/bash username0= # username0 는 선언만 되고 널로 세트됐습니다. echo "username0 = ${username0-`whoami`}" # 에코 되지 않습니다. echo "username1 = ${username1-`whoami`}" # username1 는 선언되지 않았습니다. # 에코 됩니다. username2= # username2 는 선언만 되고 널고 세트됐습니다. echo "username2 = ${username2:-`whoami`}" # 조건 테스트시 - 가 아니고 :- 를 썼기 때문에 에코 됩니다. exit 0 |
매개변수가 세트 되어 있지 않다면 기본값으로 세트.
두 형태는 거의 비슷하지만 :이 있을 때는 위의 경우처럼 $parameter가 선언만 되고 값이 널일 경우에도 기본값으로 세트 시킨다는 차이점이 있습니다 [1]
echo ${username=`whoami`} # "username" 변수를 `whoami`의 결과로 세트. |
매개변수가 세트되어 있다면 alt_value를 쓰고 아니라면 널 스트링을 씁니다.
이 두 형태는 거의 비슷하지만 parameter가 선언되고 널일 경우에 :이 있고 없고의 차이가 나타납니다. 아래를 보세요.
echo "###### \${parameter+alt_value} ########" echo a=${param1+xyz} echo "a = $a" # a = param2= a=${param2+xyz} echo "a = $a" # a = xyz param3=123 a=${param3+xyz} echo "a = $a" # a = xyz echo echo "###### \${parameter:+alt_value} ########" echo a=${param4:+xyz} echo "a = $a" # a = param5= a=${param5:+xyz} echo "a = $a" # a = # a=${param5+xyz} 와 결과가 다르죠? param6=123 a=${param6+xyz} echo "a = $a" # a = xyz |
매개변수가 세트되어 있으면 그 값을 쓰고 아니라면 err_msg를 출력.
두 형태도 역시 비슷하지만 :은 parameter가 선언만 되고 널일 경우에만 차이점이 나타납니다.
예 9-10. 매개변수 치환과 : 쓰기
#!/bin/bash # 몇개의 시스템 환경 변수 확인 # 예를 들어, 콘솔 사용자의 이름을 나타내는 $USER 가 세트 돼 있지 않다면, #+ 시스템은 여러분을 인식하지 못합니다. : ${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?} echo echo "시스템 이름은 $HOSTNAME 입니다." echo "여러분의 이름은 $USER 입니다." echo "여러분의 홈디렉토리는 $HOME 입니다." echo "여러분의 메일 INBOX는 $MAIL 에 있습니다." echo echo "이 메세지를 읽고 있다면," echo "중요한 환경 변수가 세트 되어 있다는 뜻입니다." echo echo # ------------------------------------------------------ # ${variablename?} 도 스크립트에서 변수가 세트 되어 있는지를 #+ 확인할 수 있습니다. ThisVariable=Value-of-ThisVariable # 문자열 변수는 변수 이름에 쓸 수 없는 문자가 #+ 세트될 수도 있으니 주의하세요. : ${ThisVariable?} echo "ThisVariable 의 값은 $ThisVariable." echo echo : ${ZZXy23AB?"ZZXy23AB 는 세트되지 않았습니다."} # ZZXy23AB 에 값이 세트되어 있지 않다면, #+ 에러 메세지를 뿌리고 종료할 것입니다. # 에러 메세지를 지정할 수 있습니다. # : ${ZZXy23AB?"ZZXy23AB 는 세트되지 않았습니다."} # 다음과 똑같은 결과: dummy_variable=${ZZXy23AB?} # dummy_variable=${ZZXy23AB?"ZXy23AB 는 세트되지 않았습니다."} # # echo ${ZZXy23AB?} >/dev/null echo "위에서 스크립트가 종료됐기 때문에 이 메세지는 안 보입니다." HERE=0 exit $HERE # 여기서 종료되지 *않습니다*. |
매개변수 치환과 확장. 다음 식들은 expr 문자열 연산중 match에 대해 부족한 부분을 보완해 줍니다 (예 12-6 참고). 주로, 파일 경로명을 파싱할 때 쓰입니다.
문자열 길이 ($var의 문자 갯수). 배열의 경우에, ${#array}라고 하면 배열의 첫번째 요소의 길이를 알려줍니다.
참고: 예외:
${#*} 와 ${#@} 는 위치 매개변수의 갯수를 알려줍니다.
배열에 대해 ${#array[*]} 나 ${#array[@]} 라고 하면 배열 요소의 갯수를 알려줍니다.
예 9-11. 변수의 길이
#!/bin/bash # length.sh E_NO_ARGS=65 if [ $# -eq 0 ] # 이 스크립트에서는 명령어줄 인자가 필요합니다. then echo "하나 이상의 명령어줄 인자가 필요합니다." exit $E_NO_ARGS fi var01=abcdEFGH28ij echo "var01 = ${var01}" echo "var01 의 길이 = ${#var01}" echo "스크립트로 넘어온 명령어줄 인자 갯수 = ${#@}" echo "스크립트로 넘어온 명령어줄 인자 갯수 = ${#*}" exit 0 |
$pattern이 $var의 앞 부분과 가장 길거나 가장 짧게 일치하는 부분을 삭제.
예 A-6에서 발췌한 사용법 예제:
# "days-between.sh" 예제에서 쓰인 함수. # 주어진 인자의 앞 부분에 들어있는 하나 이상의 0 을 삭제. strip_leading_zero () # 날짜나 월의 앞 부분에 나오는 0을 삭제하지 않으면 { # Bash 가 8진수로 해석하기 때문에(POSIX.2, sect 2.9.2.1) val=${1#0} # 이렇게 해 주는게 좋습니다. return $val } |
다른 사용법 예제:
echo `basename $PWD` # 현재 디렉토리의 basename. echo "${PWD##*/}" # 현재 디렉토리의 basename. echo echo `basename $0` # 스크립트 이름. echo $0 # 스크립트 이름. echo "${0##*/}" # 스크립트 이름. echo filename=test.data echo "${filename##*.}" # 데이타 # 전체 파일이름에서 확장자. |
$pattern이 $var의 뒷 부분과 가장 짧거나 가장 길게 일치하는 부분을 삭제.
Bash 버전 2에는 옵션이 더 늘었습니다.
예 9-12. 매개변수 치환에서의 패턴 매칭
#!/bin/bash # 매개변수 치환 연산자인 # ## % %% 를 써서 패턴 매칭하기. var1=abcd12345abc6789 pattern1=a*c # * (와일드 카드)는 a 와 c 사이의 모든 문자와 일치합니다. echo echo "var1 = $var1" # abcd12345abc6789 echo "var1 = ${var1}" # abcd12345abc6789 (다른 형태) echo "${var1} 에 들어 있는 글자수 = ${#var1}" echo "pattern1 = $pattern1" # a*c ('a'와 'c' 사이의 모든 문자) echo echo '${var1#$pattern1} =' "${var1#$pattern1}" # d12345abc6789 # 앞에서부터 가장 짧게 일치하는 3 글자를 삭제 abcd12345abc6789 # ^^^^^^^^^^ |-| echo '${var1##$pattern1} =' "${var1##$pattern1}" # 6789 # 앞에서부터 가장 길게 일치하는 12 글자를 삭제 abcd12345abc6789 # ^^^^^^^^^^ |----------| echo; echo pattern2=b*9 # 'b'와 '9' 사이의 모든 문자. echo "var1 = $var1" # abcd12345abc6789 를 계속 씁니다. echo "pattern2 = $pattern2" echo echo '${var1%pattern2} =' "${var1%$pattern2}" # abcd12345a # 뒤에서부터 가장 짧게 일치하는 6 글자를 삭제 abcd12345abc6789 # ^^^^^^^^^^ |----| echo '${var1%%pattern2} =' "${var1%%$pattern2}" # a # 뒤에서부터 가장 길게 일치하는 12 글자를 삭제 abcd12345abc6789 # ^^^^^^^^^^ |-------------| # 이렇게 외우세요. # # 과 ## 은 문자열의 앞쪽에서부터 동작을 하고, # % 와 %% 는 뒤쪽에서부터 동작을 합니다. echo exit 0 |
예 9-13. 파일 확장자 바꾸기:
#!/bin/bash # rfe # --- # 파일 확장자 바꾸기(Renaming file extensions). # # rfe 원래확장자 새확장자 # # 예제: # 현재 디렉토리의 *.gif 를 *.jpg 로 바꾸려면, # rfe gif jpg ARGS=2 E_BADARGS=65 if [ $# -ne $ARGS ] then echo "사용법: `basename $0` 원래확장자 새확장자" exit $E_BADARGS fi for filename in *.$1 # 첫번째 인자로 끝나는 파일 목록을 전부 탐색. do mv $filename ${filename%$1}$2 # 첫번째 인자와 일치하는 부분을 떼어내고, # 두번째 인자를 덧붙임. done exit 0 |
여기서 소개하는 것들은 ksh에서 따 온 것입니다.
var 변수가 pos 옵셋부터 시작하도록 확장.
변수 var가 pos에서 최대 len만큼의 길이를 갖도록 확장. 이 연산자의 창조적인 사용 예제를 보려면 예 A-9 참고.
var에 첫번째로 일치하는 patt을 replacement로 대치시킴.
replacement를 안 적으면 patt이 지워짐.
전역 대치(Global replacement). var에서 일치하는 모든 patt을 replacement로 대치시킴.
위의 경우와 비슷하게 replacement를 안 적어주면 모든 patt이 지워짐.
예 9-14. 임의의 문자열을 파싱하기 위해 패턴 매칭 사용하기
#!/bin/bash var1=abcd-1234-defg echo "var1 = $var1" t=${var1#*-*} echo "var1 (첫번째 - 를 포함한 부분까지 잘라냄) = $t" # # 이 가장 짧은 문자열과 매치하고 * 가 빈 문자열을 포함한 모든것과 #+ 일치하기 때문에 t=${var1#*-} 도 똑같이 동작합니다. # (S. C. 가 지적해 주었습니다.) t=${var1##*-*} echo "var1에 \"-\" 이 들어있다면 빈 문자열을 리턴함... var1 = $t" t=${var1%*-*} echo "var1 (제일 마지막의 - 부터 끝까지 잘라냄) = $t" echo # ------------------------------------------- path_name=/home/bozo/ideas/thoughts.for.today # ------------------------------------------- echo "path_name = $path_name" t=${path_name##/*/} echo "접두어가 잘려진 path_name = $t" # 이 경우에서는 t=`basename $path_name` 이라고 해도 똑같습니다. # t=${path_name%/}; t=${t##*/} 라고 하는 것이 좀 더 일반적인 해법이지만, #+ 가끔은 실패할 수도 있습니다. # $path_name 이 뉴라인으로 끝날 경우에는 `basename $path_name` 은 제대로 동작하지 않겠지만, #+ 위 표현식은 제대로 동작할 것입니다. # (Thanks, S.C.) t=${path_name%/*.*} # t=`dirname $path_name` 라고 하는 것과 똑같습니다. echo "접미어가 잘려진 path_name = $t" # 이렇게 하면 "../", "/foo////", # "foo/", "/" 같은 경우에는 실패할 것입니다. # basename 은 접미어가 없고 dirname 은 있을 경우에 접미어를 삭제하는 것 #+ 역시 복잡한 문제입니다. # (Thanks, S.C.) echo t=${path_name:11} echo "첫번째 11개 문자가 잘려나간 $path_name = $t" t=${path_name:11:5} echo "첫번째 11개 문자가 잘려나가고 길이가 5인 $path_name = $t" echo t=${path_name/bozo/clown} echo "\"bozo\" 가 \"clown\" 으로 대치된 $path_name = $t" t=${path_name/today/} echo "\"today\" 가 삭제된 $path_name = $t" t=${path_name//o/O} echo "모든 소문자 o 를 대문자로 만든 $path_name = $t" t=${path_name//o/} echo "모든 소문자 o 를 삭제한 $path_name = $t" exit 0 |
var의 접두어(prefix)가 patt과 일치하면 patt을 replacement로 치환.
var의 접미어(suffix)가 patt과 일치하면 patt을 replacement로 치환.
예 9-15. 문자열의 접두, 접미어에서 일치하는 패턴 찾기
#!/bin/bash # 문자열의 접두어/접미어 에서 패턴 치환 하기. v0=abc1234zip1234abc # 원래 변수. echo "v0 = $v0" # abc1234zip1234abc echo # 문자열의 접두어(시작)에서 일치. v1=${v0/#abc/ABCDEF} # abc1234zip1234abc # |-| echo "v1 = $v1" # ABCDE1234zip1234abc # |---| # 문자열의 접미어(끝)에서 일치. v2=${v0/%abc/ABCDEF} # abc1234zip123abc # |-| echo "v2 = $v2" # abc1234zip1234ABCDEF # |----| echo # ---------------------------------------------------- # 문자열의 시작과 끝에서 일치가 일어나야지만 #+ 대치가 일어납니다. # ---------------------------------------------------- v3=${v0/#123/000} # 일치하지만 시작 부분이 아닙니다. echo "v3 = $v3" # abc1234zip1234abc # *대치가 안 일어납니다*. v4=${v0/%123/000} # 일치하지만 끝 부분이 아닙니다. echo "v4 = $v4" # abc1234zip1234abc # *대치가 안 일어납니다*. exit 0 |
이미 선언된 변수들 중에 varprefix로 시작하는 변수들.
xyz23=whatever xyz24= a=${!xyz*} # 선언된 변수중 "xyz"로 시작하는 변수로 확장. echo "a = $a" # a = xyz23 xyz24 a=${!xyz@} # 위와 같음. echo "a = $a" # a = xyz23 xyz24 # Bash 2.04 버전에서 이 기능이 추가됨. |
[1] | 비대화형 스크립트에서 $parameter 가 널이면 127 종료 상태를 갖고 종료됩니다("command not found" 에러 코드). |