Command Line - 흐름 제어 : if 분기
[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 | file1과 file2는 동일한 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 |
string1과 string2는 같다. 등호나 이중 등호 둘 다 가능. |
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 | integer1은 interger2와 같다. |
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 명령을 통한 슈퍼유저와 일반 사용자 분기 처리 예제
출처 : 리눅스 커맨드라인 완벽 입문서