본문 바로가기

IT

[Ubuntu/Linux] 쉘스크립트 Flow control - if 문법의 모든 것

쉘스크립트를 작성하다보면,

if 문 뒤에 있는 'then'처럼 평소 C언어에서 만난 적이 없는 구문을 만나게 됩니다.

 

C언어 조건문은 if / else if / else와 같은 형태로 구성되어 있고,

쉘스크립트에서도 그와 유사하게 if / elif / else를 사용하지요.

하지만 쉘스크립트에서는 여기에 then과 fi가 추가로 들어갑니다.

 

then의 역할은 무엇일까요?

 


then의 역할을 따지기에 앞서 간단하게 문법을 살펴보겠습니다.

쉘스크립트에서 사용하는 조건문은 아래와 같은 형태입니다.


if list then list fi
if list then list else list fi
if list then list elif list then list fi
if list then list elif list then list elif list then list fi
if list then list elif list then list else list fi
if list then list elif list then list elif list else list fi


여기서 list는 다음 세 가지 중에 하나입니다.

- 간단한 명령어

- pipe(|)로 연결된 다수의 '간단한 명령어'

- '&', ';', '&&', '||'로 구분지어 연속으로 사용하는 명령어


위에서 굵은 글씨로 적힌 예약어들은 각각의 행에서 첫번째 단어로 쓰여야 합니다.

빈칸이 그 앞에 올 수는 있으나 다른 단어가 오면 안됩니다.

';'이나 '&'는 줄바꿈처럼 동작하니 그 뒤에 오는 단어는 새로운 줄의 첫번째 단어라고 생각하면 됩니다.

예약어 외에 list는 굳이 첫번째 단어가 아니어도 됩니다.

list는 예약어 뒤에 자유롭게 놓일 수 있습니다.

if true
then
  echo true
fi

위의 스크립트를 한 줄로 만들면 아래와 같습니다.

if true; then echo true; fi


위에서 보시면 if, then, fi는 예약어로서 줄의 첫번째 단어로 사용됩니다.

하지만, list 영역은 예약어 뒤에 자연스럽게 놓여져 있네요.


if 문의 조건문에는 다수의 명령어가 놓일 수 있습니다.

그 중에 제일 마지막 명령어가 if 조건문에 영향을 줍니다.

if true; false; true; then echo true; fi
true

위처럼 마지막이 true면 true를 출력하고,

false인 경우는 아무것도 출력하지 않습니다.

if true; false; then echo true; fi


실제로는 위처럼 사용하는 경우는 드물지요.

대부분은 파이프나 And/Or 연산으로 명령어를 조합하여 조건문을 만듭니다.


가장 간단한 형태의 if 문은 아래와 같습니다.

if - then - fi로 조건이 참인 경우에만 대응합니다.

if [ conditional expression ]
then
  list...
fi


예시로 if문을 하나 쉘에서 바로 만들어보겠습니다.

$ age=18
$ if [ $age -eq 18 ]
> then
> echo age is $age.
> fi
age is 18.


위에서 '$'나 '>'는 쉘에서 출력하는 프롬프트입니다.

실제로 파일로 작성하면 '$'나 '>'는 입력하지 않아야 합니다.

마지막 줄에 "age is 18"은 실시간으로 출력된 결과입니다.


if 조건문이 참/거짓 모두에 대응할 수 있게 만들어봅시다.

If [ conditional expression ]
then
  list...
else
  list...
fi

위처럼 else 구문을 추가하면 됩니다.


다시 한 번 프롬프트에서 작성해보도록 하겠습니다.

$ age=20
$ if [ $age -eq 18 ]
> then
> echo age is 18.
> else
> echo age is not 18.
> fi
age is not 18.


이제는 또 다른 조건문을 추가해보도록 하겠습니다.

elif 구문을 사용하면 됩니다.

elif 구문 뒤에 조건문을 적고 then 구문도 잊지말고 붙여야 합니다.

If [ conditional expression1 ]
then
  list...
elif [ conditional expression2 ]
then
  list...
else
  list...
fi


위의 구문은 쉘스크립트로 작성해보도록 하겠습니다.

age=80
if [ $age -lt 60 ]
then
    echo You are so young.
elif [ $age -lt 100 ]
then
    echo You are young.
else
    echo You are old.
fi

age는 80이므로 elif 문에서 참이 됩니다.

따라서 "You are young"을 출력하게 됩니다.


if 문 안에 다른 if 문을 넣을 수도 있겠지요.

스크립트로 작성할 때는 indentation을 적절하게 하여 헛갈리지 않게 하는게 좋겠지요.

If [ conditional expression1 ]
then
  list...
else
  if [ conditional expression2 ]
  then
    list...
  fi
fi


중첩 if문의 예시도 스크립트로 작성해보았습니다.

age=90
if [ $age -lt 60 ]
then
    echo You are so young.
elif [ $age -lt 100 ]
then
    if [ $age -lt 80 ]
    then
        echo You are young
    else
        echo You are still young.
    fi
else
    echo You are old.
fi


만약 if, then, elif 뒤에 놓여야할 list가 커맨트처리되는 경우도 있을 겁니다.

list에 명령어가 하나인데 커맨트처리가 되면, 리스트가 없어지는 셈입니다.

리스트가 있어야할 곳에 없으면 에러처리가 나지요.

그럴 경우 ":"를 써주어 리스트 공백을 채워주세요.

":" 하나는 조건문 자리에도 놓을 수 있습니다.

$ if :; then :; fi

위의 스크립트는 실제로는 아무 것도 수행하지 않습니다.


if문의 형태를 쭉 살펴보았는데요,

then은 (조건문의 끝이자) list의 시작을 알려주는 역할을 맡고 있습니다.

if 문 혹은 elif 문에는 다수의 조건문을 나열할 수 있기 때문에,

조건문의 끝인지 아닌지 확실하게 나타내주는 구문이 필요하지요.

오랜 고민의 결과 if 문에서는 then 문이 차용되었습니다.

실제 언어생활에서 if / then 구문을 사용하는 것처럼 이질감없이 사용하기 위해서입니다.


끝_


* References

http://www.grymoire.com/Unix/Sh.html#uh-3l