[Linux] bash 쉘 스크립트 if elif else 조건문 사용법
포스트
취소

[Linux] bash 쉘 스크립트 if elif else 조건문 사용법

bash 쉘 스크립트 if elif else 조건문 사용법

if elif else 조건문이란?

어떤 조건에 대해서 True(참)이 될 때 주어진 명령문(코드)을 실행하며, False(거짓)이면 실행하지 않는다.

종류

  • if

    if 의 조건식이 참일 때 코드가 실행됨

  • if / else

    if 의 조건식이 참이면 if 아래 코드가 실행되고 else 아래 코드는 실행되지 않음

    if 의 조건식이 거짓이면 if 아래의 코드는 실행되지 않고 else 아래 코드가 실행됨

  • if / elif / else

    • if 의 조건식이 이면 if 아래 코드가 실행되고 elif, else 아래 코드는 실행되지 않음 (elif도 참이더라도 if 가 실행됨)
    구분조건식실행 여부
    ifO
    elif-X
    else-X
    • if 의 조건식이 거짓이고 elif 의 조건식이 이면, elif 아래 코드가 실행되고 if, else 아래 코드는 실행되지 않음
    구분조건식실행 여부
    if거짓X
    elifO
    else-X
    • if 의 조건식과 elif의 조건식이 둘 다 거짓이면 if, elif 아래의 코드는 실행되지 않고 else 아래 코드가 실행됨
    구분조건식실행 여부
    if거짓X
    elif거짓X
    else-O

문법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash

if [ 조건식 ]   # 조건식에는 아래 비교 연산자를 활용
then
    명령어
elif [ 조건식 ]
then
    명령어
else
    명령어
fi

# 아래처럼 줄여서 사용도 가능하다.

if [ 조건식 ]; then
    명령어
elif [ 조건식 ]; then
    명령어
else
    명령어
fi

# 이중 괄호로 조건식을 묶으면 산술 연산자(>,< 등)를 사용할 수 있다.

if (( 조건식 )); then
    명령어
elif (( 조건식 )); then
    명령어
else
    명령어
fi

아래 연산자 관련 내용은 대부분 kldp wiki 에서 가져왔습니다. 일부 내용을 제가 보기 편하도록 수정했습니다.

파일 테스트 연산자

다음 조건이 맞다면 참을 리턴

1
2
3
4
5
6
7
8
9
10
11
-e        : 파일이 존재
-f        : 보통 파일(디렉토리나 디바이스 파일이 아님)
-s        : 파일 크기가 0 이 아님
-d        : 파일이 디렉토리
-b        : 파일이 블럭 디바이스(플로피나 시디롬 등등)
-c        : 파일이 문자 디바이스(키보드, 모뎀, 사운드 카드 등등)
-p        : 파일이 파이프
-h        : 파일이 하드 링크
-L        : 파일이 심볼릭 링크
-S        : 파일이 소켓
-t        : 파일 디스크립터가 터미널 디바이스와 연관이 있음
접기/펼치기 -t : 스크립트의 표준입력([ -t 0 ])이나 표준출력([ -t 1 ])이 터미널인지 아닌지를 확인하는데 쓸 수 있습니다.
1
2
3
4
-r        : 테스트를 돌리는 사용자가 읽기 퍼미션을 갖고 있음
-w        : 테스트를 돌리는 사용자가 쓰기 퍼미션을 갖고 있음
-x        : 테스트를 돌리는 사용자가 실행 퍼미션을 갖고 있음
-g        : 파일이나 디렉토리에 set-group-id(sgid) 플래그가 세트되어 있음
접기/펼치기 -g : 디렉토리에 sgid 플래그가 세트되어 있다면 그 디렉토리에서 만들어지는 파일은 파일 생성자의 그룹이 아니라 그 디렉토리 소유자의 그룹에 속하게 됩니다. 이는 워킹그룹이 공유하는 디렉토리에서 유용하게 쓸 수 있습니다.
1
-u        : 파일에 set-user-id(suid) 플래그가 세트되어 있음
접기/펼치기 -u : root가 소유자인 어떤 실행 파일에 set-user-id 플래그가 세트되어 있다면 일반 사용자가 그 파일을 실행시키더라도 root 권한으로 실행됩니다. [1] suid 는 시스템 하드웨어에 접근할 필요가 있는 실행 파일(pppd나 cdrecord 같은)에 유용합니다. suid 플래그가 없다면 이런 실행 파일들은 일반 사용자들이 실행시킬 수 없습니다. -rwsr-xr-t 1 root 178236 Oct 2 2000 /usr/sbin/pppd suid 플래그가 걸린 파일은 퍼미션에 s라고 나타납니다.
1
-k        : 스티키 비트(sticky bit)가 세트
접기/펼치기 -k : 보통은 "스키키 비트"라고 알려져 있는 세이브-텍스트-모드(save-text-mode) 플래그는 특별한 형태의 파일 퍼미션입니다. 어떤 파일에 이 플래그가 세트되어 있다면 그 파일은 더 빠른 접근을 위해 캐쉬 메모리에 계속 남아 있습니다. [2] 만약에 디렉토리에 세트되어 있다면 쓰기 퍼미션을 제한합니다. 스티키 비트가 세트되어 있다면 파일이나 디렉토리 퍼미션에 t 가 붙어서 보입니다. drwxrwxrwt 7 root 1024 May 19 21:26 tmp/ 사용자는 자기가 소유하지는 않고 쓰기 퍼미션과 스티키 비트가 세트되어 있는 디렉토리에 오직 자신이 소유한 파일만 지울 수 있습니다. 이렇다면 /tmp처럼 공동으로 접근 가능한 디렉토리에서 여러 사용자가 실수로 다른 사용자의 파일을 지우거나 덮어 쓰는 것을 막아 줍니다.
1
2
3
4
5
6
7
-O        : 자신이 소유자임
-G        : 그룹 아이디가 자신과 같음
-N        : 마지막으로 읽힌 후에 변경됐음
f1 -nt f2 : f1 파일이 f2 파일보다 최신임
f1 -ot f2 : f1 파일이 f2 파일보다 예전 것임
f1 -ef f2 : f1 파일과 f2 파일이 같은 파일을 하드 링크하고 있음
!         : "not" -- 앞에서 나왔던 테스트의 의미와 반대(조건이 안 맞으면 참).

산술 비교 연산자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-eq       : 두 수가 같음(equal)
            if [ "$a" -eq "$b" ]

-ne       : 두 수가 같지 않음(not equal)
            if [ "$a" -ne "$b" ]

-gt       : 왼쪽이 오른쪽보다 더 큼(greater than)
            if ["$a" -gt "$b" ]

-ge       : 왼쪽이 오른쪽보다 더 크거나 같음(greater than or equal)
            if [ "$a" -ge "$b" ]

-lt       : 왼쪽이 오른쪽보다 더 작음(less than)
            if [ "$a" -lt "$b" ]

-le       : 왼쪽이 오른쪽보다 더 작거나 같음(less than or equal)
            if [ "$a" -le "$b" ]

[ 부등호는 이중 소활호 (()) 에서 사용할 수 있다. ]
<         : 왼쪽이 오른쪽보다 더 작음
            if (( "$a" < "$b" ))

<=        : 왼쪽이 오른쪽보다 더 작거나 같음
            if (( "$a" <= "$b" ))

>         : 왼쪽이 오른쪽보다 더 큼
            if (( "$a" > "$b" ))

>=        : 왼쪽이 오른쪽보다 더 크거나 같음
            if (( "$a" >= "$b" ))

문자열 비교 연산자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
=         : 두 문자열이 같음
            if [ "$a" = "$b" ]

==        : 두 문자열이 같음 ('=' 와 같은 동작)
            if [ "$a" == "$b" ]

            [[ $a == z* ]]    # $a 가 "z"로 시작하면 참(패턴 매칭)
            [[ $a == "z*" ]]  # $a 가 z* 와 같다면 참

            [ $a == z* ]      # 파일 globbing이나 낱말 조각남이 일어남
            [ "$a" == "z*" ]  # $a 가 z* 와 같다면 참

!=        : 두 문자열이 같지 않음
            if [ "$a" != "$b" ]

            [ 부등호는 이중 대괄호 [[]] 에서 이스케이프 없이 사용할 수 있다. ]

<         : 왼쪽이 오른쪽보다 아스키 알파벳 순서에서 더 작음
            if [[ "$a" < "$b" ]] 또는,
            if [ "$a" \< "$b" ]

            '<' 를 [ ] 에서 쓰려면 이스케이프 시켜야 한다.

>         : 왼쪽이 오른쪽보다 아스키 알파벳 순서에서 더 큼
            if [[ "$a" > "$b" ]]
            if [ "$a" \> "$b" ]

            '>' 를 [ ] 에서 쓰려면 이스케이프 시켜야 한다.

-z        : 문자열이 "null"임. 즉, 길이가 0

-n        : 문자열이 "null"이 아님.

논리 연산자

1
2
3
4
5
6
7
-a        : 논리 and
            if [ "$exp1" -a "$exp2" ] 는 exp1 과 exp2 모두 참일 경우에만 참을 리턴합니다.
            [[ condition1 && condition2 ]] 와 비슷하다.

-o        : 논리 or
            if [ "$exp1" -o "$exp2" 는 exp1 이나 exp2 중 하나라도 참일 경우에 참을 리턴합니다.
            [[ condition1 || condition2 ]] 와 비슷하다.

주의 사항

공백 필수!

조건문이 들어가는 대괄호([,]) 양쪽 사이에 공백이 한 칸 꼭 들어가야 한다.

예를 들어, if ["$1" -eq "abc"] 와 같이 사용하면 에러가 발생한다.

잘못된 문법올바른 문법
if ["$1" = "abc"]if [ "$1" = "abc" ]
괄호 사이 공백 없음 

변수 활용 시 따옴표!

조건문에 변수를 활용할 때 변수를 꼭 따옴표로 묶어주는 습관을 들이자.

변수가 비어있을 때, 공백이 들어가는 형태가 되어버려서 에러가 발생한다.

따옴표로 묶어주면, 공백이 아니라 비어있는 문자열로 인식되어 에러가 발생하지 않는다.

잘못된 문법올바른 문법
if [ $variable = "wrong" ]if [ "$variable" -eq "correct" ]
쉘은 if [ -eq "wrong" ] 이렇게 인식함 (에러 발생) 

( variable 변수는 비어있는 상태 )

참고 자료

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

[Linux] bash 쉘 스크립트 변수 사용 시 주의사항(중괄호)

[Linux] bash 쉘 스크립트 함수 반환 값(리턴) 받기