IT일반/Linux

Command Line - 흐름 제어 : if 분기

버섯도리 2022. 6. 3. 18:00
[cmd_test@btjeon-naver ~]$ vi if_test.sh
---------------------------------------------------------------------------------------------
#!/bin/bash

x=5

if [ $x = 5 ]; then
        echo "x equals 5."
else
        echo "x does not equal 5."
fi
---------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./if_test.sh 
x equals 5.
[cmd_test@btjeon-naver ~]$ x=5
[cmd_test@btjeon-naver ~]$ if [ $x = 5 ]; then echo "x equals 5."; else echo "x does not equal 5."; fi
x equals 5.
[cmd_test@btjeon-naver ~]$ x=0
[cmd_test@btjeon-naver ~]$ if [ $x = 5 ]; then echo "x equals 5."; else echo "x does not equal 5."; fi
x does not equal 5.

if 분기문 사용 예제

 

<File 표현식>

표현식 표현식이 참인 경우...
file1 -ef file2 file1file2는 동일한 inode를 가진다. (하드 링크에 의해 두 파일명은 동일한 파일을 참조하게 된다.)
file1 -nt file2 file1 file2보다 최신이다.
file1 -ot file2 file1 file2보다 오래되었다.
-b file file1 존재하고 이 파일은 블록 특수 파일이다.
-c file file1 존재하고 이 파일은 문자 특수 파일이다.
-d file file1 존재하고 이 파일은 디렉토리이다.
-e file file1 존재한다.
-f file file1 존재하고 이 파일은 일반 파일이다.
-g file file1 존재하고 이 파일은 setgid가 설정되어 있다.
-G file file1 존재하고 이 파일은 유효 그룹 ID의 소유다.
-k file file1 존재하고 이 파일은 "sticky 비트"를 가지고 있다.
-L file file1 존재하고 이 파일은 심볼릭 링크다.
-O file file1 존재하고 이 파일은 유효 사용자 ID의 소유다.
-p file file1 존재하고 이 파일은 네임드 파이프다.
-r file file1 존재하고 이 파일은 읽기 전용이다.
-s file file1 존재하고 이 파일은 파일 크기가 0보다 큰 파일이다.
-S file file1 존재하고 이 파일은 네트워크 소켓이다.
-t fd fd 터미널이 지정된 파일 디스크립터다. 이것으로 표준 입력/출력/오류의 리다이렉션 여부를 확인할 수 있다.
-u file file1 존재하고 이 파일은 setuid가 설정되어 있다.
-w file file1 존재하고 이 파일은 쓰기가 가능하다.
-x file file1 존재하고 이 파일은 실행이 가능한 파일이다.

 

[cmd_test@btjeon-naver ~]$ vi test_file.sh 
---------------------------------------------------------------------------------------------
#!/bin/bash

# test_file: Evaluate the status of a file

FILE=~/.bashrc

if [ -e "$FILE" ]; then
        if [ -f "$FILE" ]; then
                echo "$FILE is a regular file."
        fi
        if [ -d "$FILE" ]; then
                echo "$FILE is a directory."
        fi
        if [ -r "$FILE" ]; then
                echo "$FILE is readable."
        fi
        if [ -w "$FILE" ]; then
                echo "$FILE is writable."
        fi
        if [ -x "$FILE" ]; then
                echo "$FILE is executable/searchable/"
        fi
else
        echo "$FILE does not exist.."
        exit 1
fi

exit
---------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_file.sh 
/home/cmd_test/.bashrc is a regular file.
/home/cmd_test/.bashrc is readable.
/home/cmd_test/.bashrc is writable.

파일 검사 스크립트 예제

 

[cmd_test@btjeon-naver ~]$ vi test_file_func.sh
------------------------------------------------------------------------------------------
test_file () {

        # test_file: Evaluate the status of a file

        FILE=~/.bashrc

        if [ -e "$FILE" ]; then
                if [ -f "$FILE" ]; then
                        echo "$FILE is a regular file."
                fi
                if [ -d "$FILE" ]; then
                        echo "$FILE is a directory."
                fi
                if [ -r "$FILE" ]; then
                        echo "$FILE is readable."
                fi
                if [ -w "$FILE" ]; then
                        echo "$FILE is writable."
                fi
                if [ -x "$FILE" ]; then
                        echo "$FILE is executable/searchable/"
                fi
        else
                echo "$FILE does not exist.."
                return 1
        fi

}
------------------------------------------------------------------------------------------

파일 검사 함수를 정의하는 스크립트 예제. 다른 프로그램에서 포함시켜 사용하고자 할 때.

 

<문자열 표현식>

표현식 표현식이 참인 경우...
string string은 null이 아니다.
-n string string의 길이는 0보다 크다.
-z string string의 길이는 0이다.
string1 = string2
string1 == string2
string1string2는 같다. 등호나 이중 등호 둘 다 가능.
string1 != string2 string1 string2는 같지 않다.
string1 > string2 string1 string2보다 뒤에 정렬된다.
string1 < string2 string1 string2보다 앞에 정렬된다.

 

[cmd_test@btjeon-naver ~]$ vi test_string.sh
----------------------------------------------------------------------------------------
#!/bin/bash

# test_string: Evaluate the status of a string

ANSWER=maybe

if [ -z "$ANSWER" ]; then
        echo "There is no answer." >&2
        exit 1
fi

if [ "$ANSWER" = "yes" ]; then
        echo "The answer is YES."
elif [ "$ANSWER" = "no" ]; then
        echo "The answer is NO."
elif [ "$ANSWER" = "maybe" ]; then
        echo "The answer is MAYBE."
else
        echo "The answer is UNKNOWN."
fi
----------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_string.sh 
The answer is MAYBE.

문자열 검사 스크립트 예제

 

<정수 표현식>

표현식 표현식이 참인 경우...
integer1 -eq integer2 integer1interger2와 같다.
integer1 -ne integer2 integer1 interger2와 같지 않다.
integer1 -le integer2 integer1 interger2와 작거나 같다.
integer1 -lt integer2 integer1 interger2와 작다.
integer1 -ge integer2 integer1 interger2와 크거나 같다.
integer1 -gt integer2 integer1 interger2와 크다.

 

[cmd_test@btjeon-naver ~]$ vi test_integer.sh
-------------------------------------------------------------------------------------------
#!/bin/bash

# test_integer: Evaluate the status of an integer.

INT=-5

if [ -z "$INT" ]; then
        echo "INT is empty." >&2
        exit 1
fi

if [ $INT -eq 0 ]; then
        echo "INT is zero."
else
        if [ $INT -lt 0 ]; then
                echo "INT is negative."
        else
                echo "INT is positive."
        fi
        if [ $((INT % 2)) -eq 0 ]; then
                echo "INT is even."
        else
                echo "INT is odd."
        fi
fi
-------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer.sh 
INT is negative.
INT is odd.

정수 검사 스크립트 예제

 

[cmd_test@btjeon-naver ~]$ vi test_integer2.sh
---------------------------------------------------------------------------------------------
#!/bin/bash

# test_integer2: Evaluate the value of an integer.

INT=-5

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."
                fi
                if [ $((INT % 2)) -eq 0 ]; then
                        echo "INT is even."
                else
                        echo "INT is odd."
                fi
        fi
else
        echo "INT is not an integer.">$2
        exit 1
fi
---------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer2.sh 
INT is negative.
INT is odd.

[[ ]] 명령식과 문자열 표현식 연산자인 =~를 사용하여 상수가 정수인지를 식별하는 표현식을 만들수 있다.

 

[cmd_test@btjeon-naver ~]$ FILE=foo.bar
[cmd_test@btjeon-naver ~]$ if [[ $FILE == foo.* ]]; then
> echo "$FILE matches pattern 'foo.*'"
> fi
foo.bar matches pattern 'foo.*'

[[ ]] 명령식은 == 연산자로 경로명 확장과 똑같은 방식의 패턴 찾기를 지원한다.

 

[cmd_test@btjeon-naver ~]$ if ((1)); then echo "It is true."; fi
It is true.
[cmd_test@btjeon-naver ~]$ if ((0)); then echo "It is true."; fi
[cmd_test@btjeon-naver ~]$
[cmd_test@btjeon-naver ~]$ vi test_integer2a.sh
-------------------------------------------------------------------------------------------
#!/bin/bash

# test_integer2a: Evaluate the value of an integer.

INT=-5

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
        if ((INT == 0)); then
                echo "INT is zero."
        else
                if ((INT < 0)); then
                        echo "INT is negative."
                else
                        echo "INT is positive."
                fi
                if (( ((INT % 2)) ==  0 )); then
                        echo "INT is even."
                else
                        echo "INT is odd."
                fi
        fi
else
        echo "INT is not an integer.">$2
        exit 1
fi
-------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer2a.sh 
INT is negative.
INT is odd.

(( )) 명령식은 산술식의 참 여부를 검사한다. (정수 표현식이 한결 자연스러워 보인다.)

 

<논리 연산자>

논리 연산 test [[ ]], (( ))
AND -a &&
OR -o ||
NOT ! !

 

[cmd_test@btjeon-naver ~]$ vi test_integer3.sh
-------------------------------------------------------------------------------------------
#!/bin/bash

# test_integer3: Determine if an integer is within a specified range of values.

MIN_VAL=1
MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
        if [[ INT -ge MIN_VAL && INT -le MAX_VAL ]]; then
                echo "$INT is within $MIN_VAL to $MAX_VAL."
        else    
                echo "$INT is out of range"
        fi
else
        echo "INT is not an integer.">$2
        exit 1
fi
-------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer3.sh 
50 is within 1 to 100.

[[ ]] 표현식에서 && 연산자 사용 예제

 

[cmd_test@btjeon-naver ~]$ vi test_integer3a.sh
---------------------------------------------------------------------------------------------
#!/bin/bash

# test_integer3a: Determine if an integer is within a specified range of values.

MIN_VAL=1
MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
        if (( INT >= MIN_VAL && INT <= MAX_VAL )); then
                echo "$INT is within $MIN_VAL to $MAX_VAL."
        else
                echo "$INT is out of range."
        fi
else
        echo "INT is not an integer.">$2
        exit 1
fi
---------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer3a.sh 
50 is within 1 to 100.

(( )) 명령식 사용

 

[cmd_test@btjeon-naver ~]$ vi test_integer3b.sh
-------------------------------------------------------------------------------------------
#!/bin/bash

# test_integer3b: Determine if an integer is within a specified range of values.

MIN_VAL=1
MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
        if [ $INT -ge $MIN_VAL -a $INT -le $MAX_VAL ]; then
                echo "$INT is within $MIN_VAL to $MAX_VAL."
        else
                echo "$INT is out of range"
        fi
else
        echo "INT is not an integer.">$2
        exit 1
fi
-------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer3b.sh 
50 is within 1 to 100.

[ ] test 명령어에서 -a 연산자 사용 예제

 

[cmd_test@btjeon-naver ~]$ vi test_interger4.sh
--------------------------------------------------------------------------------------------
#!/bin/bash

# test_integer4: Determine if an integer is outside a specified range of values.

MIN_VAL=1
MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
        if [[ ! (INT -ge MIN_VAL && INT -le MAX_VAL) ]]; then
                echo "$INT is outside $MIN_VAL to $MAX_VAL."
        else
                echo "$INT is in range."
        fi
else
        echo "INT is not an integer.">$2
        exit 1
fi
--------------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer4.sh 
50 is in range.

! 부정 연산자 사용 예제

 

[cmd_test@btjeon-naver ~]$ vi test_integer4b.sh
-----------------------------------------------------------------------------------------
#!/bin/bash

# test_integer4b: Determine if an integer is outside a specified range of values.

MIN_VAL=1
MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
        if [ ! \( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL \) ]; then
                echo "$INT is outside $MIN_VAL to $MAX_VAL."
        else
                echo "$INT is in range."
        fi
else
        echo "INT is not an integer.">$2
        exit 1
fi
-----------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ ./test_integer4b.sh 
50 is in range.

[ ] test 명령어에서 ! 연산자 사용 예제

 

 

test는 전통적으로 쓰이는 명령어(그리고 POSIX의 일부분)인 반면, [[ ]] 명령식은 bash에 특화되어 있다.

[[ ]] 명령식은 test 명령어 사용법보다 훨씬 유용하고 코딩하기 쉽다고 할 수 있다.

 

[cmd_test@btjeon-naver ~]$ mkdir temp && cd temp
[cmd_test@btjeon-naver temp]$ cd ..
[cmd_test@btjeon-naver ~]$ [ -d temp ] && cd temp
[cmd_test@btjeon-naver temp]$

 

bash는 분기를 수행할 수 있는 두 개의 연산자를 제공한다.

command1 && command2 : command1과 command2 모두 실행되면 command1이 성공했다는 것을 의미한다.

command1 || command2 : command1과 command2 모두 실행되면 command1이 실패했다는 것을 의미한다.

 

[ -d temp] || exit 1

스크립트를 생성할 때, 위와 같은 코드를 통해 temp 디렉토리가 존재하지 않으면 스크립트가 종료 상태 1을 반환하고 종료되도록 작성할 수 있다.

 

[cmd_test@btjeon-naver ~]$ vi sys_info_page_here2
---------------------------------------------------------------------------------------
...
report_home_space() {
        if [[ $(id -u) -eq 0 ]]; then
                cat <<- _EOF_
                        <H2>Home Space Utilization (All Users)</H2>
                        <PRE>$(du -sh /home/*)</PRE>
                        _EOF_
        else
                cat <<- _EOF_
                        <H2>Home Space Utilization ($USER)</H2>
                        <PRE>$(du -sh $HOME)</PRE>
                        _EOF_
        fi
        return
}
...
---------------------------------------------------------------------------------------
[cmd_test@btjeon-naver ~]$ vi sys_info_page_here2
[cmd_test@btjeon-naver ~]$ ./sys_info_page_here2
...
		<H2>Home Space Utilization (cmd_test)</H2>
<PRE>5.8M	/home/cmd_test</PRE>
...

id 명령을 통한 슈퍼유저와 일반 사용자 분기 처리 예제

 

 

 

 

 

 

출처 : 리눅스 커맨드라인 완벽 입문서