본문 바로가기

스터디/리눅스 커맨드라인

[리눅스] 27. 흐름 제어: if 분기

우리가 작성 중인 보고서 생성 스크립트가 실행될 때 사용자 권한에 따라 결과를 어떻게 조정할 수 있을까?
이 문제에 대한 해결책은 스크립트 내에서 테스트 결과에 따라 방량을 바꾸는 방법을 찾는데 있다.
프로그래밍식으로 말하면, 프로그램을 분기할 필요가 있다.

 

 

1. if의 사용

1) 쉘

x = 5

if [$x = 5]; then
	echo "x equals 5."
else
	exho "x does not equal 5."
fi

x=5라는 조건을 만족하면 "x는 5다" 라고 출력이 되고, 그렇지 않으면 "x는 5가 아니다라는 문구가 출력이 되는 코드이다.

2) 커맨드라인

$ x=5
$ if [$x = 5]; then echo "equals 5"; else echo "does not equal 5";
equals 5

 

 

2. 종료 상태

명령어들은 종료될 때 종료 상태라는 값을 생성한다. 이 값은 0부터 255까지 사이의 정수로 명령어 실행의 성공 여부에 대한 정보를 나타낸다. 일반적으로, 0은 성공을 나타내고 그 외의 다른 숫자는 실패를 가리킨다. 

# 성공
$ ls -d /usr/bin
/usr/bin

$ echo $?
0

# 실패
$ ls -d /bin/usr
ls:error
$ echo $?
2​
첫 번째 ls 명령어에서 $? 매개변수의 값이 0임을 확인할 수 있다는 것은 명령어가 성공적이었다는 것이고, 두 번째 ls 명령어는 2가 출력되었으므로 실패를 의미한다. 

 

3. test의 사용

test 명령어는 다양한 검사비교 작업을 수행할 수 있다.
"test expression" 이런 커맨드로도 사용되고, 가장 많이 쓰이는 형태인 "[expression]" 형태이다.
"expression"에는 명령어 성공 여부를 검사하는 표현식이 들어간다. test 명령어는 이 표현식이 참이면 0, 거짓이면 1의 종료 상태 값을 반환한다.

1) 파일 표현식
if [ -e "$FILE" ]; then
	if [ -f "$FILE" ]; then
    		echo "$FILE is a regular file."
    
    if [ -d "$FILE" ]; then
    	echo "$FILE is a directory."
        
else
	echo "$FILE does not exist"
    exit 1
    
exit​

만약 $FILE이 존재한다면( -e file ), $FILE이 일반파일일 경우 ( -f file ) "is a regular file."을 출력한다. $FILE이 존재하고 읽기 전용이면 ( -r file ) "directory"를 출력한다.

스크립트에서 exit 명령어는 선택적으로 하나의 명령 인자와 함께 사용될 수 있는데 이 인자는 스크립트의 종료 상태를 나타낸다.
명령 인자를 사용하지 않으면 종료 상태는 기본적으로 0이다. 이런 식으로 exit를 스크립트상에서  사용하여 $FILE 매개변수가 존재하지 않는 파일명을 가리킬 경우 실패를 나타내도록 한다. 마지막 exit 명령어는 형식적으로 사용한 것이다. 스크립트가 끝까지 실행되면 기본적으로 종료 상태 값 0으로 스크립트가 종료된다.

 

4. 현대식 테스트

bash 최신 버전에는 test 역할을 대신하는 합셩 명령어를 지원한다. 

"[[ expression ]] "
"expression"에는 참/거짓을 판단하는 표현식을 입력한다. [[ ]] 명령식은 test와 매우 흡사하나 중요한 새 문자열 표현식이 추가된다.

"string1 =~ regex"
만일 string1이 확장 정규 표현식인 regex에 부합하면 참을 반환하는 표현식이다. 이것은 데이터 유효성 작업을 수행하는 등 다양한 가능성을 제공한다.

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
	if [ $INT -eq 0 ]; then
    	echo "INT is zero"
    else 
    	if [ $INT -lt 0 ]; then
        	echo "INT is negative"
        else
        	echo "INT is positive"
        
        if [$((INT % 2)) -eq 0 ]; then
        	echo "INT is even"
        else
        	echo "INT is odd"
        
else
	echo "INT is not an integer." >&2
    exit 1​

정규 표현식을 적용함으로써 상수 INT 값을 하나 이상의 숫자 값을 가진 경우로 제한할 수 있다.
마이너스 기호는 있을 수도 없을 수도 있다. 또한 이 정규표현식은 빈 값의 존재 가능성도 제거해주었다.