지금 여러분이 시스템에서 쓰고 있는 Bash 는 버전 2.XX 대 입니다.
bash$ echo $BASH_VERSION 2.04.21(1)-release |
예 35-1. 문자열 확장
#!/bin/bash # 문자열 확장. # Bash 버전 2 부터 소개됨. # $'xxx' 형태의 문자열들은 표준 이스케이프 문자로 해석됩니다. echo $'벨 3번 울리기 \a \a \a' echo $'3번의 폼피드(form feed) \f \f \f' echo $'10번의 뉴라인(newline) \n\n\n\n\n\n\n\n\n\n' exit 0 |
예 35-2. 간접 변수 참조 - 새로운 방법
#!/bin/bash # 변수 간접 참조. # C++ 의 참조 특성이 약간 가미되었습니다. a=letter_of_alphabet letter_of_alphabet=z echo "a = $a" # 직접 참조. echo "Now a = ${!a}" # 간접 참조. # ${!variable} 표기법은 예전의 "eval var1=\$$var2" 보다 훨씬 좋습니다. echo t=table_cell_3 table_cell_3=24 echo "t = ${!t}" # t = 24 table_cell_3=387 echo "t 의 값이 ${!t} 로 바뀌었습니다." # 387 # 배열이나 테이블 멤버를 참조할 때나 #+ 다차원 배열을 시뮬레이션 할 경우에 쓸 만 합니다. # 인덱싱을 옵션으로 가졌다면 더 좋았을 겁니다(휴~~). exit 0 |
예 35-3. 배열과 약간의 트릭을 써서 한 벌의 카드를 4명에게 랜덤하게 돌리기
#!/bin/bash # 오래된 시스템이라면 #!/bin/bash2 로 실행시켜야 할지도 모릅니다. # 카드: # 카드 한 벌을 4명에게 무작위로 돌리기. UNPICKED=0 PICKED=1 DUPE_CARD=99 LOWER_LIMIT=0 UPPER_LIMIT=51 CARDS_IN_SUIT=13 CARDS=52 declare -a Deck declare -a Suits declare -a Cards # 하나짜리 3차원 배열이라면 더 쉽고 더 직관적이었을 겁니다. # 아마 Bash 다음 버전에서는 다차원 배열을 지원할 겁니다. initialize_Deck () { i=$LOWER_LIMIT until [ "$i" -gt $UPPER_LIMIT ] do Deck[i]=$UNPICKED # 카드 "한 벌"(deck)을 모두 안 고른 상태로 둠. let "i += 1" done echo } initialize_Suits () { Suits[0]=C # 클로버(Clubs) Suits[1]=D # 다이아몬드(Diamonds) Suits[2]=H # 하트(Hearts) Suits[3]=S # 스페이드(Spades) } initialize_Cards () { Cards=(2 3 4 5 6 7 8 9 10 J Q K A) # 배열을 초기화하는 또 다른 방법. } pick_a_card () { card_number=$RANDOM let "card_number %= $CARDS" if [ "${Deck[card_number]}" -eq $UNPICKED ] then Deck[card_number]=$PICKED return $card_number else return $DUPE_CARD fi } parse_card () { number=$1 let "suit_number = number / CARDS_IN_SUIT" suit=${Suits[suit_number]} echo -n "$suit-" let "card_no = number % CARDS_IN_SUIT" Card=${Cards[card_no]} printf %-4s $Card # 카드를 칸 단위로 깔끔하게 출력. } seed_random () # 랜덤 넘버 발생기 seed. { seed=`eval date +%s` let "seed %= 32766" RANDOM=$seed } deal_cards () { echo cards_picked=0 while [ "$cards_picked" -le $UPPER_LIMIT ] do pick_a_card t=$? if [ "$t" -ne $DUPE_CARD ] then parse_card $t u=$cards_picked+1 # 임시로 1 부터 인덱싱하는 형태로 바꿈. let "u %= $CARDS_IN_SUIT" if [ "$u" -eq 0 ] # 중첩된 if/then 조건 테스트. then echo echo fi # 다른 사람. let "cards_picked += 1" fi done echo return 0 } # 구조적 프로그래밍: # 전체 프로그램 로직은 함수로 모듈화 되어 있습니다. #================ seed_random initialize_Deck initialize_Suits initialize_Cards deal_cards exit 0 #================ # 연습문제 1: # 전체에 대해 완전한 주석을 달아보세요. # 연습문제 2: # 한 사람이 받은 카드를 종류순으로 정렬해서 보여주도록 고쳐보세요. # 필요하다면 편리한 다른 기능을 써도 괜찮습니다. # 연습문제 3: # 스크립트를 간략화하고, 합리적인 로직이 되도록 고쳐보세요. |
[1] | Chet Ramey 는 펄에서 쓰이는 연관 배열(associative arrays) 을 다음 Bash 에서 사용할 수 있도록 하겠다고 약속했습니다. |