[쉘 스크립트] 쉘 스크립트 기초 - 조건문 (2)

업데이트:     Updated:

카테고리:

태그:

🎯구조적 명령 (1) - 조건문

if-then 구문

다른 프로그래밍 언어와 비교했을 때 bash 쉘의 if 문은 조건을 평가하는 방식에 차이점이 있다.

  • 다른 프로그래밍 언어에서는 TRUE 또는 FALSE를 평가하는 표현식을 사용한다.
  • bash 쉘은 if문 뒤에 정의된 command을 실행한다. 이 command의 종료 상태가 0이라면 then 이하의 명령을 실행하고 종료 상태가 0이 아니라면 then 이하의 명령은 실행되지 않는다.
  • bash 쉘에서 if-then 구문의 기본 문법은 다음과 같다.
if command; then
  commands
fi

OR

if command
then
  commands
fi

if-then-else 구문

if-then 구문에서 조건을 평가할 command의 종료 상태가 0인 경우 then 이하의 명령이 실행되지만 0이 아닌 경우 bash 쉘은 스크립트의 다음 명령으로 넘어간다. 이때 다음 명령으로 넘어가지 않고 else 이하의 명령이 실행되도록 if-then-else 구문을 활용할 수 있다.

if command; then
  commands
else
  commands
fi

if-then-elif-then 구문

if-then 구문에서 하나 이상의 조건 평가 명령을 사용하려면 if-then-elif-then 구문을 사용할 수 있다.

if command1
then
  commands
elif command2
then
  commands
else
  commands
fi

TEST 명령

테스트 명령은 if-then 구문에서 여러 가지 조건을 테스트하는 방법을 제공한다.

  • 테스트 명령에 나와있는 조건이 참으로 평가되면 테스트 명령은 종료 상태 코드로 0을 반환한다.
  • 조건이 거짓이면 test 명령은 0이 아닌 상태 코드를 돌려주므로 if-then 구문에서 빠져 나오게 된다.
  • 테스트 명령의 기본 문법은 다음과 같다.
test condition

# condition은 테스트 명령이 평가할 일련의 명령 및 매개변수다.

if-then 구문에서 TEST 명령 사용

if-then 구문에서 TEST 명령을 사용하면 다른 프로그래밍 언어의 if-then 구문과 무척 비슷하게 동작하도록 할 수 있다.

if test condition
then
  commands
else
  commands
fi
  • test 명령의 condition 부분을 비워 놓으면 0이 아닌 종료 상태 코드로 종료되므로 else 블록 문으로 넘어간다.
  • 조건을 추가하면 테스트 명령이 이를 테스트한다. 예를 들어, 테스트 명령을 사용하여 어떤 변수가 값을 가지고 있는지를 판단할 수 있다.
  • bash 쉘에서는 if-then 구문에서 test 명령을 사용하는 다른 방법을 제공한다. 다음은 그 예시이다.
if [ condition]
then
  commands
fi

Note:

대괄호는 테스트 조건을 정의한다. 한 가지 주의할 점이 있다. 여는 대괄호 뒤와 닫는 대괄호 앞에 각각 빈 칸이 있어야 한다. 안 그러면 오류 메시지가 나타난다.

TEST 명령에서 세 가지 종류의 조건을 평가하는 방법


  • 숫자 비교
  • 문자열 비교
  • 파일 비교

숫자, 문자열, 파일 비교

숫자 비교 설명 문자열 비교 설명
n1 -eq n2           n1과 n2가 같은지 검사한다. str1 == str2 str1이 str2와 같은지 검사한다.
n1 -ge n2 n1이 n2보다 크거나 같은지 검사한다. str != str2           str1이 str2와 같지 않은지 검사한다.
n1 -gt n2 n1이 n2보다 큰지 검사한다. str1 < str2 str1이 str2보다 작은지 검사한다.
n1 -le n2 n1이 n2보다 작거나 같은지 검사한다. st1 > str2 str1이 str2보다 큰지 검사한다.
n1 -lt n2 n1이 n2보다 작은지 검사한다. -n str1 str1의 길이가 0보다 큰지 검사한다.
n1 -ne n2 n1과 n2가 같지 않은지 검사한다. -z str1 str1의 길이가 0인지 검사한다.
파일 비교 설명
-d file 파일이 존재하고 디렉토리인지 검사한다.
-e file 파일이 존재하는지 검사한다.
-f file 파일이 존재하고 파일인지 검사한다.
-r file 파일이 존재하고 읽을 수 있는지 검사한다.
-s file 파일이 존재하고 비어 있지 않은지 검사한다.
-w file 파일이 존재하고 기록할 수 있는지 검사한다.
-x file 파일이 존재하고 실행할 수 있는지 검사한다.
-O file 파일이 존재하고 현재 사용자가 소유한 것인지 검사한다.
-G file 파일이 존재하고 기본 그룹이 현재 사용자의 기본 그룹과 같은지 검사한다.
file1 -nt file2 file1이 file2 보다 새것인지 검사한다.(파일이 존재하지 않으면 실패한 상태를 돌려준다.)
file1 -ot file2 file1이 file2 보다 오래된 것인지 검사한다. (파일이 존재하지 않으면 실패한 상태를 돌려준다.)       

Note:

  1. 숫자 조건 테스트를 할 때는 부동소수점 값을 사용할 수 없다.
  2. 문자열이 같은지 비교할 때에는 모든 문장부호와 대문자도 고려된다.
  3. 파일을 비교할 때 파일의 경로는 스크립트를 실행하는 디렉토리를 기준으로 한 상대 경로다.

문자열 비교 시 주의할 점

bash 쉘에서 어떤 문자열이 다른 문자열 보다 큰지 작은지를 판단할 때 주의할 점이 있다. 바로 부등호 기호를 이스케이프 해야하는 것이다 그렇지 않으면 쉘은 이를 리다이렉트 기호로 해석한다.

$ cat badtest.sh
#!/bin/bash

val1=baseball
val2=hockey

if [ $val1 > $val2 ]
then
  echo "$val1 is greater then $val2"
else
  echo "$val1 is less then $val2"
fi

$ ./badtest.sh
baseball is greater then hockey
$ cat hockey
baseball

위 결과에서 >는 출력 리다이렉트 기호로 해석됐다. 그 결과 hockey 파일에 val1 변수 값이 저장되었고 TEST 문은 리다이렉트가 성공적으로 완료되었기 때문에 종료 상태 코드 0을 돌려주었다.

이 문제를 해결하려면 > 부등호를 이스케이프 처리해야 한다.

문자열 크기

-n-z 비교는 변수에 데이터가 포함되어 있는 지 여부를 평가하려고 할 때 유용하게 사용될 수 있다.

$ cat test.sh
#!/bin/bash

val1=testing
val2=''

if [ -n $val1 ]
then
  echo "The string '$val1' is not empty"
else
  echo "The string '$val1' is empty"
fi

if [ -z $val2 ]
then
  echo "The string '$val2' is empty"
else
  echo "The string '$val2' is not empty"
fi

if [ -z $val3 ]
then
  echo "The string '$val3' is empty"
else
  echo "The string '$val3' is not empty"
fi

$ ./test.sh
The string 'testing' is not empty
The string '' is empty
The string '' is empty

Note:

쉘 스크립트에서 정의되지 않은 val3 변수 또한 문자열 길이를 0으로 간주한다.

&&(AND), ||(OR) 연산

if-then 구문을 사용할 때 테스트를 결합하는 부울 논리 연산자를 사용할 수 있다.

[ condition ] && [ condition2]
[ condition ] || [ condition2]

첫 번쨰 부울 연산은 두 가지 조건을 AND 연산자로 결합한다. then 섹션이 실행되기 위해서는 두 가지 조건을 모두 만족해야 한다. 두 번째 부울 연산은 두 가지 족너을 OR 연산자로 결합한다. 어느 한쪽이라도 조건이 참으로 평가되면 then 섹션이 실행된다.

고급 if-then

bash 쉘의 두 가지 추가 기능은 if-then 구문에서 사용할 수 있는 고급 기능을 제공한다.

  • 수학 표현식을 위한 이중 괄호
  • 고급 문자열 처리 기능을 위한 이중 대괄호

이중 괄호

이중 괄호 명령은 숫자 비교에서 간단한 산술 연산을 할 수 있다. 이중 괄호 명령의 형식은 다음과 같다.

(( expression ))
  • expression에는 수식 또는 비교 표현식이 들어갈 수 있다. test 명령에서 쓰이는 표준 ㅜ학 연산자 이외에도 이중 괄호 명령 안에 들어갈 수 있는 추가 연산자 목록이 있다.
  • 이중 괄호는 if 문의 비교 시에도 사용할 수 있고 스크립트에서 값을 할당하기 위한 일반 명령에도 사용할 수 있다.
  • 이중 괄호를 사용하면 수식 안에서 부등호에 이스케이프 처리를 할 필요가 없다.
기호 설명 기호 설명 기호 설명 기호 설명 기호 설명
val++     후위 증가 val--      후위 감소 ++val      전위 증가 --val      전위 감소 **         지수화                    
<< 비트를 왼쪽으로 시프트      >> 비트를 오른쪽으로 시프트      & 비트 단위 부울 AND      | 비트 단위 부울 OR         
&& 논리 AND || 논리 OR ! 논리 부정 ~ 비트 부정    
$ cat test.sh
#!/bin/bash

val1=10

if (( $val1 ** 2 > 90 ))
then
   (( val2 = $val1 ** 2 ))
   echo "The square of $val1 is $val2"
fi

$ ./test.sh
The square of 10 is 100

이중 대괄호

이중 대괄호 명령은 문자열 비교에 대한 고급 기능을 제공한다. 이중 대괄호 명령의 형식은 다음과 같다.

[[ expression]]
  • 이중 대괄호 표현식은 테스트 명령 평가의 표준 문자열 비교를 사용한다. 추가로 일반 TEST 명령에서는 사용할 수 없는 추가 기능도 제공한다. 바로 패턴 일치이다.
  • 패턴 일치에서는 문자열 값과 비교할 정규표현식을 정의할 수 있다.
$ cat test.sh
#!/bin/bash

if [[ $USER == r* ]]
then
  echo "Hello $USER"
else
  echo "Sorry, I do not know you"
fi

[root]$ ./test.sh
Hello root

case 명령

변수의 값을 평가할 때 가능한 몇 가지 값들 중 하나에 해당하는지 확인할 때가 있다. 이때 elif 또는 case 문을 사용할 수 있다.

case variable in 
pattern1 | parttern2)
  commands;;
pattern3)
  commands;;
*)
  commands;;
esac
  • case 명령은 지정된 변수를 여러 패턴으로 비교한다. 변수가 패턴과 일치하면 쉘은 패턴에 지정된 명령을 실행한다.
  • 한 줄에 한 가지 이상의 패턴을 사용할 수 있으며 이때는 (|)연산자로 각 패턴을 분리해야 한다.
  • (*)기호는 나열된 패턴 중 어느 것과도 일치하지 않는 모든 값을 수용한다. 다음은 case 문을 사용하는 예이다.
$ cat test.sh
#!/bin/bash

case $USER in
root | admin)
  echo "Welcome, $USER"
  echo "Please enjoy your visit";;
jessica)
  echo "Do not forget to log off when you're done";;
*)
  echo "Sorry, you are not allowed here";;
esac

[root]$ ./test.sh
Welcome, root
Please enjoy your visit

📖출처

리처드 블룸, 크리스틴 브레스, ⌜리눅스 커맨드라인 쉘 스크립트 바이블⌟, 스포트라잇북(2016)


👍 개인 공부 기록용 블로그입니다. 오류나 조언이 있으시면 언제든지 댓글 혹은 메일로 남겨주시면 감사하겠습니다! 😄

맨 위로 이동하기

Linux 카테고리 내 다른 글 보러가기

댓글남기기