1. 조건문
1) case 구문
#!/bin/bash
cat << EOF
-----------------------------------------------------------------
(1) who (2) date (3)pwd
-----------------------------------------------------------------
EOF
echo -n "Enter your choice? : "
read NUM1
case $NUM1 in
1) who ;;
2) date ;;
3) pwd ;;
*) echo "Error"
exit 1 ;;
esac
case구문의 경우 case VAR in ~ esac 로 구성되어 있으며, VAR은 변수이다, in ~ esac 사이엔 숫자로 넘버링이 가능하며, 넘버링 끝에는 ;; 로 끝을 알리며, 나머지선택지의 대한 값은 *)로 표현이 된다.
1-1) yes or no
#!/bin/bash
echo -n " Enter Your Choice? (yes/no) : "
read ANSWER
case $ANSWER in
y|Y|yes|Yes|YES) echo "YES" ;;
n|N|no|No|NO) echo "NO" ;;
*) echo " Don't understand the answer ! "
exit 1 ;;
esac
위 경우처럼 넘버링이 아닌 입력받을 조건을 여러가지로 둘 수 있다, 이때 또는을 뜻하는 구분자는 | (파이프) 기호이며 and의 의미를 갖는다.
1-2) service를 키고 끄자
예제1)
#!/bin/bash
USAGE() {
echo " Usage : $0 <service> {start|stop|restart|status}"
}
SERVICENAME=$1
ACTION=$2
case $ACTION in
start) systemctl start $SERVICENAME
systemctl enable $SERVICENAME ;;
stop) systemctl stop $SERVICENAME
systemctl disable $SERVICENAME ;;
restart) systemctl restart $SERVICENAME ;;
status) systemctl status $SERVICENAME ;;
*) USAGE
exit 1 ;;
esac
서비스 데몬을 키고 끄는 양식이다, 이처럼 명령문도 적용 가능하고, 함수값으로도 가능하다, 특수변수들과 함수를 활용하면 더욱 효율적인 코드를 만들 수 있다.
case 구문 내 if 구문도 섞어서 활용 할 수 있다.
#!/bin/bash
USAGE() {
echo " Usage : $0 <service> {start|stop|restart|status}"
}
if [ $# -ne 2 ] ; then
USAGE
exit 1
fi
SERVICENAME=$1
ACTION=$2
STATUS=$(systemctl is-active $SERVICENAME)
case $ACTION in
start) systemctl start $SERVICENAME >/dev/null 2>&1
systemctl enable $SERVICENAME >/dev/null 2>&1
if [ $STATUS = 'active' ] ; then
echo "[ OK ] Starting $SERVICENAME"
else
echo "[ FAIL ] Starting $SERVICENAME"
fi
;;
stop) systemctl stop $SERVICENAME >/dev/null 2>&1
systemctl disable $SERVICENAME >/dev/null 2>&1
if [ $STATUS = 'inactive' ] ; then
echo "[ OK ] Stoping $SERVICEANME"
else
echo "[ FAIL ] Stoping $SERVICEANME"
fi
;;
restart) systemctl restart $SERVICENAME ;;
status) systemctl status $SERVICENAME ;;
*) USAGE
exit 1 ;;
esac
이처럼 if 구문을 섞어서도 동작이 가능하다, 위의경우에 정상 동작시 [ OK ] 출력되며, 비정상동작시 [ FAIL ] 로 출력이 된다
service.sh 수정.
2. 반복구문
반복구문은 여러가지 리스트를 반복시켜서 실행시켜주는 동작을 의미한다.
1) for 구문 ( 단순반복 )
for 구문은 for VAR in VAR_list do ~ done 으로 이루어져 있다. VAR_list 내에 있는값을 VAR 내에 한번씩 넣어서 do ~ done 사이의 내용을 실행하는 방식이다. 예제를 보면 이해가 빠르다
#!/bin/bash
for VAR in 1 2 3 4
do
echo $VAR
done
[root@linux200 ~/bin]# for.sh
1
2
3
4
1 이 VAR에 한번 들어가서 출력되고 다음으로 2 ,3, 4 순차적으로 리스트가 모두 출력완료되면 종료되는형식이다.
1-1) 파일안의 내용을 리스트화 하자.
#!/bin/bash
FTPUSERS=/etc/vsftpd/ftpusers
for NAME in $(cat $FTPUSERS | egrep -v '^$|^#')
do
echo $NAME
done
/etc/vsftpd/ftpusers 에는 ftp 사용가능 유저들의 목록이 있다. 중간에 주석처리(#) 또는 공백을 제외하고 유저의 리스트를 뽑아서 변수리스트로 지정할 수 도 있다, 리스트를 일일이 나열하는것이 아닌 파일을 활용하여 적용할때 cat 과 grep를 활용할 수 있다.
2) while 구문 ( 무한반복 )
while 구문의 경우 while (참) do ~ done 으로 구성되어있다. 참일경우 do ~ done 을 실행하고 거짓이 이 되면 종료한다, 즉 참이 계속 반복되는 값이 있을 경우 거짓이 될때 까지 반복하여 적용되는 구문이다. 예시를 보자
#!/bin/bash
while [ $# -gt 0 ]
do
echo "$# : $*"
shift
done
[root@linux200 ~/bin]# shift.sh 1 2 3 4 5 6
6 : 1 2 3 4 5 6
5 : 2 3 4 5 6
4 : 3 4 5 6
3 : 4 5 6
2 : 5 6
1 : 6
예시 처럼 echo "$# : $*" -> shift 의 값이 [ $# -gt 0 ] (인자의 개수가 0 보다 큰경우) 가 아닐경우까지 계속 반복되는것을 볼 수 있다.
3) loop 구문
반복구문 내에서 반복을 멈추거나, 계속할 수 있도록 하는 명령어이다.
3-1) break
break (숫자) 로 구성되며. 반복구문중 break 를 만나면 해당 수에 맞는 위치의 반복끝 구문으로 이동시킨다.
while [조건1]
do
statement1
while [조건2]
do
statement2
while [조건3]
do
statement3
[조건4] && break Number
statement4
done # break 1 ( 조건2로 시작 )
done # break 2 ( 조건 1로 시작 )
done # break 3 ( 끝 )
break는 반복구의 탈출용도로 활용된다.
3-2) continue
continue (숫자) 로 구성되며. 반복구문중 continue 를 만나면 해당 수에 맞는 위치의 반복시작 구문으로 이동시킨다.
while [조건1] # continue 3
do
statement1
while [조건2] # continue 2
do
statement2
while [조건3] # continue 1
do
statement3
[조건4] && continue Nunber
statement4
done
done
done
* continue는 반복구를 다시 실행하기 위해 활용된다.
3-3) 로그 모니터링 ( continue 활용 )
로그 모니터링하는 파일을 제작해보자 부정적인 단어가 로그에 새롭게 쌓일경우 root에게 메일을 관련내용으로 보내는 프로그램이다.
#!/bin/bash
LOG1=/var/log/messages
TMP1=/tmp/.tmp1
TMP2=/tmp/.tmp2
TMP3=/tmp/.tmp3
egrep -i 'warn|fail|error|crit|alert|emerg' $LOG1 > $TMP1
while true
do
sleep 10
egrep -i 'warn|fail|error|crit|alert|emerg' $LOG1 > $TMP2
diff $TMP1 $TMP2 > $TMP3 && continue
mailx -s "[ WARNING ] $LOG1" root < $TMP3
egrep -i 'warn|fail|error|crit|alert|emerg' $LOG1 > $TMP1
done
3-4) FTP server 와 유사한 프로그램
FTP 처럼 입력을 받으면 그의 값이 출력되는 프로그램을 만들어보자
#!/bin/bash
HELP() {
cat <<EOF
Commands may be abbreviated. Commands are:
! debug mdir sendport site
$ dir mget put size
account disconnect mkdir pwd status
EOF
}
QUIT() {
echo " Good Bye FTP server ^^"
exit 0
}
while true
do
echo -n "ftp> "
read CMD
case $CMD in
'help') HELP;;
'quit') QUIT;;
*) ?INvalid command
esac
done
위처럼 while true 를 통해 무한반복되는 반복문을 통해 원하는 값을 입력시 원하는 결과가 출력되도록 case 구문과 함깨 활용하면 ftp server 와 유사한 파일을 제작할 수 있다.
[참고] for, while 비교
예제 1)
#!/bin/bash
FTPUSERS=/etc/vsftpd/ftpusers
for NAME in $(cat $FTPUSERS | egrep -v '^$|^#')
do
echo $NAME
done
예제 2)
#!/bin/bash
FTPUSERS=/etc/vsftpd/ftpusers
cat $FTPUSERS | egrep -v '^$|^#' | while read SARAM
do
echo $SARAM
done
위 두 내용은 동일한 결과값을 출력한다, 예제2의 경우 입력값 출력값 (IO) 를 파이프를 활용해서 받은걸 확인할 수 있다 이런걸 IO Redirection 이라고 한다
[root@linux200 ~/bin]# cat saram.txt
user01 file1
user02 file2
user03 file3
# 이 내용을 갖고있는 파일을 쪼개보자
예제1)
#!/bin/bash
for i in $(cat saram.txt)
do
echo $i
done
[root@linux200 ~/bin]# test.sh
user01
file1
user02
file2
user03
file3
예제2)
#!/bin/bash
cat saram.txt | while read SA FI
do
echo "$SA $FI"
done
[root@linux200 ~/bin]# test.sh
user01 file1
user02 file2
user03 file3
위 예제를 보면 for 구문의 경우는 값을 하나하나 쪼개서 쓰긴 어렵다, 이럴경우에는 while 구문을 활용할 시 파일 내 값을 하나하나 쪼개쓰는게 더욱 유리하다.
'모의해킹 침해대응 과정 > 본 과정' 카테고리의 다른 글
쉘 프로그래밍(bash)_3 / day31 (0) | 2021.05.10 |
---|---|
쉘 프로그래밍(bash)_2 / day30 (0) | 2021.05.07 |
쉘 프로그래밍(bash)_1 / day29 (0) | 2021.05.06 |
쉘 스크립트(bash)_1 / day28 (0) | 2021.05.04 |
쉘 스크립트(bash) / day28 (0) | 2021.05.04 |