8.1. 연산자(Operators)

할당(assignment)

변수 할당

변수값을 초기화 하거나 변경하기

=

산술식과 문자열 할당을 해주는 다기능 할당 연산자.

var=27
category=minerals  # "=" 다음에 빈 칸이 들어가면 안 됩니다.

경고

"=" 할당 연산자와 = 테스트 연산자를 헷갈리면 안 됩니다.

#    테스트 연산자인 =

if [ "$string1" = "$string2" ]
# if [ "Xstring1" = "Xstring2" ] 라고 해야 변수 값이 비어 있을 경우에
# 발생할지도 모를 에러를 막아주기 때문에 더 안전합니다.
# "X"는 상쇄되어 없어집니다.
then
   command
fi

산술 연산자(arithmetic operators)

+

더하기

-

빼기

*

곱하기

/

나누기

**

누승(exponentiation)
# Bash 2.02 버전에서 누승 연산자인 "**"가 소개됐습니다.

let "z=5**3"
echo "z = $z"   # z = 125

%

modulo 나 mod (정수 나누기에서 나머지 값)

bash$ echo `expr 5 % 3`
2
	      

이 연산자는 특정 범위에 속하는 숫자를 만들어 내거나(예 9-19, 예 9-20) 결과를 특정 포맷으로 만들어 주거나(예 26-6) 심지어는 소수(prime number)를 만들어내는데(예 A-11) 쓸 수도 있습니다.

+=

"plus-equal"(상수값 만큼 증가)

let "var += 5"var의 값을 5만큼 증가시킵니다.

-=

"minus-equal"(상수값 만큼 감소)

*=

"times-equal"(상수값을 곱함)

let "var *= 4"var의 값에 4배를 해 줍니다.

/=

"slash-equal"(상수값으로 나눔)

%=

"mod-equal"(상수값으로 나눈 나머지 값)

산술 연산자는 종종 expr 이나 let 식에서 쓰입니다.

예 8-1. 산술 연산자 쓰기

#!/bin/bash
# 5가지의 다른 방법으로 6까지 세기.

n=1; echo -n "$n "

let "n = $n + 1"   # let "n = n + 1"   이라고 해도 됩니다.
echo -n "$n "

: $((n = $n + 1))
#  ":" 가 없으면 Bash가 "$((n = $n + 1))"을 
#+ 명령어로 해석하려고 하기 때문에 필요합니다.
echo -n "$n "

n=$(($n + 1))
echo -n "$n "

: $[ n = $n + 1 ]
#  ":" 가 없으면 Bash가 "$[n = $n + 1]"을 
#+ 명령어로 해석하려고 하기 때문에 필요합니다.
#  "n"이 문자열로 초기화 되어 있어도 동작합니다.
echo -n "$n "

n=$[ $n + 1 ]
#  "n"이 문자열로 초기화 되어 있어도 동작합니다.
#* 이런 형태는 더 이상 지원되지 않고 이식성도 없기 때문에 쓰지 마세요.
echo -n "$n "; echo

# Thanks, Stephane Chazelas.

exit 0

참고: Bash 의 정수 변수는 실제로는 범위가 -2147483648 에서 2147483647 까지인 signed long(32-bit) 정수입니다. 그렇기 때문에 이 범위를 벗어나는 변수를 쓰면 에러가 납니다.
a=2147483646
echo "a = $a"      # a = 2147483646
let "a+=1"         # "a" 를 증가.
echo "a = $a"      # a = 2147483647
let "a+=1"         # "a" 를 다시 증가, 제한 범위를 벗어남.
echo "a = $a"      # a = -2147483648
                   #      ERROR (out of range)

경고

Bash 는 부동 소수점 연산을 이해하지 못합니다. 점이 들어간 숫자는 단순히 문자열로 취급됩니다.
a=1.5

let "b = $a + 1.3"  # 에러.
# t2.sh: let: b = 1.5 + 1.3: syntax error in expression (error token is ".5 + 1.3")
echo "b = $b"       # b=1
부동 소수점 연산이나 수학 함수들이 필요하다면 bc 를 쓰세요.

비트 연산자(bitwise operators). 비트 연산자는 쉘 스크립트에서 자주 쓰이지 않습니다. 이런 연산자들은 주로 포트나 소켓에서 값을 읽고 테스트하고 조작하는데 쓰입니다. "비트 조작(bit flipping)"은 C나 C++ 처럼 실행중에 비트연산을 할 수 있을 정도로 충분히 속도가 빠른 컴파일 언어가 더 알맞습니다.

비트 연산자

<<

비트 왼쪽 쉬프트(쉬프트 한 번당 2를 곱하는 것과 동일함)

<<=

"left-shift-equal"

let "var <<= 2"var2 비트만큼 왼쪽으로 쉬프트(4 를 곱하는 것과 동일함)

>>

비트 오른쪽 쉬프트(쉬프트 한 번당 2로 나눔)

>>=

"right-shift-equal"(<<=와 반대)

&

비트 and

&=

"비트 and-equal"

|

비트 OR

|=

"비트 OR-equal"

~

비트 negate

!

비트 NOT

^

비트 XOR

^=

"비트 XOR-equal"

논리 연산자(logical operators)

&&

and (논리)

if [ $condition1 ] && [ $condition2 ]
# if [ condition1 -a condition2 ] 와 같음
# condition1과 condition2가 모두 참일경우 참을 리턴...

if [[ $condition1 && $condition2 ]]    # 역시 동작함.
# && 연산자는 [ ... ] 에서 쓰일 수 없습니다. 주의하세요.

참고: && 는 상황에 따라 명령어들을 연결해 주는 and 리스트로도 쓰일 수도 있습니다.

||

or (논리적)

if [ $condition1 ] || [ $condition2 ]
# if [ condition1 -o condition2 ] 와 같음
# condition1이나 condition2중 하나만 참이면 참을 리턴...

if [[ $condition1 || $condition2 ]]    # 역시 동작함.
# || 연산자는 [ ... ] 에서 쓰일 수 없습니다. 주의하세요.

참고: Bash는 논리 연산자로 연결된 각 문장의 종료 상태를 테스트합니다.

예 8-2. && 와 || 를 쓴 복합 조건 테스트

#!/bin/bash

a=24
b=47

if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]
then
  echo "첫번째 테스트 성공."
else
  echo "첫번째 테스트 실패."
fi

# 에러:    if [ "$a" -eq 24 && "$b" -eq 47 ]
#          라고 하면 ' [ "$a" -eq 24 ' 를 실행시키려고 하기 때문에
#          해당하는 ']' 를 찾지 못해 에러가 납니다.
#
#    if [[ $a -eq 24 && $b -eq 24 ]]   라고 하면 되겠죠.
#    (6번째 줄과 17번째 줄의 "&&" 는 다른 뜻을 갖습니다.)
#    Thanks, Stephane Chazelas.


if [ "$a" -eq 98 ] || [ "$b" -eq 47 ]
then
  echo "두번째 테스트 성공."
else
  echo "두번째 테스트 실패."
fi


# 복합문 조건 테스트에서는 -a 와 -o 옵션을 쓸 수도 있습니다.
# 이 점을 지적해준 Patrick Callahan 에게 감사합니다.


if [ "$a" -eq 24 -a "$b" -eq 47 ]
then
  echo "세번째 테스트 성공."
else
  echo "세번째 테스트 실패."
fi


if [ "$a" -eq 98 -o "$b" -eq 47 ]
then
  echo "네번째 테스트 성공."
else
  echo "네번째 테스트 실패."
fi


a=rhino
b=crocodile
if [ "$a" = rhino ] && [ "$b" = crocodile ]
then
  echo "다섯번째 테스트 성공."
else
  echo "다섯번째 테스트 실패."
fi

exit 0

&&|| 연산자는 산술식에서도 쓰일 수 있습니다.

bash$ echo $(( 1 && 2 )) $((3 && 0
)) $((4 || 0)) $((0 || 0))
1 0 1 0
          

기타 연산자(miscellaneous operators)

,

콤마 연산자(comma operator)

콤마 연산자는 두 개 이상의 산술 연산을 묶어 줍니다. 이 연산자로 묶인 모든 연산은 부효과(side effects)가 생길 가능성을 가지고 평가되고 제일 마지막 연산의 결과만 리턴됩니다.

let "t1 = ((5 + 3, 7 - 1, 15 - 4))"
echo "t1 = $t1"               # t1 = 11

let "t2 = ((a = 9, 15 / 3))"  # "a" 를 세트하고 "t2" 를 계산.
echo "t2 = $t2    a = $a"     # t2 = 5    a = 9

콤마 연산자는 주로 for 루프에서 쓰입니다. 예 10-11를 참고하세요.