리눅스상에서 trace dump, logging, 기타 작업들을 손쉽게 해주는 툴을 제작 중에 있습니다.
아직 미완성이지만 일부만 올려봅니다. 나중에 완성되면 완성본을 올리겠습니다.
아래는 core menu 실행화면입니다. CUI 환경에서도 interactive 하게 동작되도록 whiptail을 이용하여 제작하였습니다.
<main menu>
<tracedump menu>
<KDUMP Warning>
<DropCache, Search data by Index, Find History>
<History Period Setup>
아래는 sysman 유틸리티의 core script 일부분입니다.
#!/bin/bash # This script code is SysMan(SystemManager) core menu. clear ###### Load config for sysman ###### if [ -f ./conf_sysman ]; then . ./conf_sysman else . core/conf_sysman fi export SYSMANDIR=$SYSMANDIR ###### Load config for sysman ###### ###### Functions Start ###### ## Funtion of random number ## randomcount () { MAXCOUNT=10 count=1 while [ "$count" -le $MAXCOUNT ] do rannum=$RANDOM let "count += 1" done RANGE=1024 FLOOR=0 rannum=0 while [ "$rannum" -le $FLOOR ] do rannum=$RANDOM let "rannum %= $RANGE" done } ## Funtion of user check ## is_root () { if [ "$EUID" -eq 0 ]; then return 0; else WHO=$(whoami) return 1; fi } ## Funtion of define for window size ## calc_wt_size() { WT_HEIGHT=17 WT_WIDTH=$(tput cols) if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then WT_WIDTH=80 fi if [ "$WT_WIDTH" -gt 178 ]; then WT_WIDTH=120 fi WT_MENU_HEIGHT=$(($WT_HEIGHT-12)) } ## Funtion of progress bar ## PROGSLEEP=0.5 PROGCOUNT=2 progress_bar() { PER=$(bc <<< "100/$PROGCOUNT") for ((i=$PER ; i<=100 ; i+=$PER)) do echo $i sleep $PROGSLEEP MAX=$(bc <<< "100-$i") if [ $PER -gt $MAX ]; then if ! [ $MAX -eq 0 ]; then echo 100 fi fi done } check_log_status () { MAX=100 sleep 0.1 while true do if [ "$LOGCHK" = "0" ]; then break; fi if [ $MAX -eq 0 ]; then break; fi sleep 0.1 let MAX-=1 done # { # if [ $MAX -eq 0 ]; then # echo "" # fi # } | whiptail --msgbox "* TIMEOVER" 10 60 } running_check () { MAXCHK=1 while [ 1 ] do if [ -n $LOGCHKDIR ]; then grep _Running `eval echo $LOGCHKDIR` >& /dev/null if [ $? = 0 ]; then break; fi fi if [ $MAXCHK -eq 100 ]; then echo "카운트가 $MAXCHK 을 넘었습니다." >> $LOGCHKDIR whiptail --msgbox "$LOGCHKDIR 체크 실패. $LOGCHKDIR 로그를 확인하세요." 12 100 break fi sleep 0.1 #let MAXCHK+=1 #let "MAXCHK += 1" #(( MAXCHK ++ )) MAXCHK=$[$MAXCHK +1] done } ## Funtion of do_monitor ## function do_monitor { CHOICE=$(whiptail --title "<<Log Manger>>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT \ "P PortMonitor" " - 정의된 네트워크 포트 모니터링 및 로깅 >>" \ "L LogMaker " " - 정의된 양식의 결과값 로깅 >>" \ 3>&1 1>&2 2>&3) RET=$? if [ $RET = 1 ]; then return 0 elif [ $RET = 0 ]; then case "$CHOICE" in P\ *) do_monitor_port ;; L\ *) do_monitor_logmaker ;; *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; esac || whiptail --msgbox "There was an error running option $CHOICE" 20 60 1 fi } ## Funtion of do_monitor_port ## function do_monitor_port { randomcount CONFIGS=$(cat $SYSMANDIR/apps/portmonitor/portmonitor.conf | egrep -v '^#|^$') whiptail --yesno "*지정된 client 포트를 모니터링합니다.\n\n*설정파일: $SYSMANDIR/apps/portmonitor/portmonitor.conf\n\n*설정현황:\n$CONFIGS\n\n\n 모니터링을 시작하시겠습니까?" 20 60 1 RET=$? if [ $RET = 0 ]; then { { $SYSMANDIR/apps/portmonitor/portmonitor.sh } 1> $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum 2>&1 & PID=$! sleep 0.2 PORTSS=$(grep PORTS $SYSMANDIR/apps/portmonitor/portmonitor.conf | grep -v ^#) INT=$(grep Interval $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum | awk -F ": " '{print $2}') BTI=$(grep Break $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum | awk -F ": " '{print $2}' | awk -F '' '{print $1$2$3$4"."$5$6"."$7$8". "$9$10}') LOG=$(grep Log $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum | awk -F ": " '{print $2}') if [ -z "$INT" ]; then RESULT="*포트모니터링 실행에 문제가 발생했습니다.\n문제점: `sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum`" else RESULT="*포트모니터링이 시작되었습니다.\n\n*실행정보: PID '$PID'로 '$PORTSS'을 Interval '$INT'간격으로 '$BTI'시까지 수행됩니다.\n*로그위치: $LOG" fi rm -f $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum echo $RESULT > result_tmp"$rannum" progress_bar } | whiptail --gauge "Getting data ..." 6 60 0 read -r result_tmp`` < result_tmp"$rannum" rm -f result_tmp"$rannum" whiptail --msgbox "$result_tmp" 12 120 #result_tmp="" else return 0 fi } function do_monitor_logmaker { randomcount ls $SYSMANDIR/apps/logmaker/*.conf >& /dev/null CONFSTATUS=$? read -ra confs <<< $(ls $SYSMANDIR/apps/logmaker/*.conf | grep -n "" | awk '{print $NF}' | sed 's/\://g' | awk -F "/" '{print $NF; print "<"$1">"}') OPTION=$(whiptail --title "<<<Log Maker>>>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT "${confs[@]}" 3>&1 1>&2 2>&3) RET=$? if [ $CONFSTATUS = 0 ]; then if [ $RET = 0 ]; then CONFIGS=$(cat $SYSMANDIR/apps/logmaker/$OPTION | egrep -v '^#|^$') whiptail --yesno "*정의된 command로 로깅을 시작합니다.\n\n*설정파일: $SYSMANDIR/apps/logmaker/$OPTION\n\n*설정현황:\n$CONFIGS\n\n\n 로깅을 시작하시겠습니까?" 20 100 1 RET1=$? if [ "$RET1" = 0 ]; then { { $SYSMANDIR/apps/logmaker/logmaker.sh "--conf=$OPTION" } 1> $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum 2>&1 & PID=$! sleep 0.2 COMMAND=$(grep COMMAND $SYSMANDIR/apps/logmaker/"$OPTION" | grep -v ^#) INT=$(grep Interval $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | awk -F ": " '{print $2}') BTI=$(grep Finish $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | awk -F ": " '{print $2}') LOG=$(grep Log $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | awk -F ": " '{print $2}') if [ -z "$INT" ]; then RESULT="*로깅 실행에 문제가 발생했습니다.\n문제점: `sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | head -2`" else RESULT="*로깅이 시작되었습니다.\n\n*실행정보: PID '$PID'로 '$COMMAND'을 '$INT'초 간격으로 '$BTI'시까지 수행됩니다.\n*로그위치: $LOG" fi rm -f $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum echo $RESULT > result_tmp"$rannum" progress_bar } | whiptail --gauge "Getting data ..." 6 60 0 read -r result_tmp`` < result_tmp"$rannum" rm -f result_tmp"$rannum" whiptail --msgbox "$result_tmp" 12 100 #whiptail --msgbox "$(cat "$SYSMANDIR/apps/logmaker/tmp_logmaker$rannum")" 12 120 #rm -f $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum else do_monitor_logmaker fi else return 0 fi elif [ $CONFSTATUS = 2 ]; then whiptail --msgbox "*config 파일이 없습니다.\n$SYSMANDIR/apps/logmaker 디렉토리로 이동 후 XX.conf를 생성하십시오." 12 100 else return 0 fi } function do_etc { CHOICE=$(whiptail --title "<<ETC Manager>>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT \ "D DROPCACHE " " - Buffers/Cached 메모리 정리 >>" \ "S SEARCH FILE" " - Index를 통한 파일/디렉토리 찾기 >>" \ "L SEARCH HISTORY" " - History를 통한 command 기록 찾기 >>" \ 3>&1 1>&2 2>&3) RET11=$? if [ $RET11 = 1 ]; then return 0 elif [ $RET11 = 0 ]; then case "$CHOICE" in D\ *) do_etc_dropcache ;; S\ *) do_etc_find ;; L\ *) do_etc_loginhist ;; *) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;; esac || whiptail --msgbox "There was an error running option $CHOICE" 20 60 1 fi } function do_etc_dropcache { if is_root ; then randomcount whiptail --yesno "*System Buffer/Cached 메모리를 정리합니다.\n\n*주의: 시스템 I/O 사용량이 없을때 실행하십시오.\n\n\n 실행 하시겠습니까?" 15 60 1 RET=$? if [ $RET = 0 ]; then { { $SYSMANDIR/apps/dropcache/do_drop_cache.sh } 1> $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum 2>&1 & PID=$! sleep 0.2 LOG=$(grep log $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum) if [ -z $LOG ]; then RESULT="*Drop Cache에 문제 발생.\n$LOG 로그파일을 확인하십시오." else RESULT="*Drop Cache가 잘 수행되었습니다.\n결과LOG파일 :" fi #rm -f $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum PROGSLEEP=0.5 PROGCOUNT=10 progress_bar MAXCOUNT=100 while true do if [ $MAXCOUNT -eq 1 ]; then RESULT="Log 생성 시간이 초과되었습니다.\n $LOG 파일이 정상인지 확인 하십시오." break fi grep END $LOG >& /dev/null if [ $? = 0 ]; then break fi sleep 0.2 let MAXCOUNT-=1 done echo $RESULT > result_tmp"$rannum" } | whiptail --gauge "Drop the Buffers/Cached of Memory 수행 중 ..." 6 50 0 read -r result_tmp`` < result_tmp"$rannum" rm -f result_tmp"$rannum" whiptail --msgbox "$result_tmp $(cat "$SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum")" 25 80 rm -f $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum else return 0 fi else whiptail --msgbox "You are not root. You are $WHO\nCan be run only root." 20 60 1 fi } ## Funtion of do_dump ## function do_dump { if is_root ; then randomcount APP="apps/dumpman" ls $SYSMANDIR/$APP/*.conf >& /dev/null CONFSTATUS=$? read -ra confs <<< $(ls $SYSMANDIR/$APP/*.conf | grep -n "" | awk '{print $NF}' | sed 's/\://g' | awk -F "/" '{print "\""$NF"\""; print "\"<"$1">\""; print "OFF"}') OPTION=$(whiptail --title "<<Dump Manger>>" --checklist "선택한 항목들에 대한 dump를 수집합니다." 15 60 6 "${confs[@]}" 3>&1 1>&2 2>&3) RET=$? if [ $CONFSTATUS = 0 ]; then if [ $RET = 0 ]; then if [ -z "$OPTION" ]; then whiptail --msgbox "* No Selected. Select, please." 12 100 do_dump fi echo $OPTION | grep 'vmcore_kdump' >& /dev/null if [ $? = 0 ]; then LOGDIR=$(echo `grep ^LOGDIR $SYSMANDIR/$APP/dumpman.sh | head -1 | awk -F "=" '{print $2}'`) if [ -d `eval echo "$LOGDIR"` ]; then eval rm -f "$LOGDIR/dump_logcheck[1-9]*" eval touch $LOGDIR/dump_logcheck$rannum else mkdir -p `eval echo "$LOGDIR"` eval touch $LOGDIR/dump_logcheck$rannum fi sleep 0.1 export LOGCHKDIR="$LOGDIR/dump_logcheck$rannum" while [ 1 ] do whiptail --inputbox "***주의**** vmcore_kdump를 선택하셨습니다.\n*아래에 $rannum 을 입력 후 진행하면 커널패닉이 발생됩니다." 8 70 --title "RUN KDUMP" 2>> $SYSMANDIR/core/tmp_kdump_$rannum RET2=$? if [ $RET2 = 0 ]; then grep $rannum $SYSMANDIR/core/tmp_kdump_$rannum >& /dev/null RET3=$? if [ $RET3 = 1 ]; then whiptail --msgbox "* 숫자를 잘 못 입력하셨습니다." 10 60 cat /dev/null > $SYSMANDIR/core/tmp_kdump_$rannum rm -f $SYSMANDIR/core/tmp_kdump_$rannum else sed -i 's/^ENABLE.*/ENABLE="yes"/' $SYSMANDIR/$APP/vmcore_kdump.conf break fi else rm -f $SYSMANDIR/core/tmp_kdump_$rannum do_dump fi done rm -f $SYSMANDIR/core/tmp_kdump_$rannum elif [ $? = 1 ]; then LOGDIR=$(echo `grep ^LOGDIR $SYSMANDIR/$APP/dumpman.sh | head -1 | awk -F "=" '{print $2}'`) if [ -d `eval echo "$LOGDIR"` ]; then eval rm -f "$LOGDIR/dump_logcheck[1-9]*" eval touch $LOGDIR/dump_logcheck$rannum else mkdir -p `eval echo "$LOGDIR"` eval touch $LOGDIR/dump_logcheck$rannum fi sleep 0.1 export LOGCHKDIR="$LOGDIR/dump_logcheck$rannum" fi { read -ra selectlist <<< $(echo $OPTION | sed 's/\"\"//g') for i in "${selectlist[@]}" do { # dumpman.sh runs independently of this script. (The line below) nohup $SYSMANDIR/$APP/dumpman.sh --conf="$i" # dumpman.sh runs dependently of this script. If this script is finished and dumpman.sh is over. (The line below) # $SYSMANDIR/$APP/dumpman.sh --conf="$i" & } 1>> $SYSMANDIR/$APP/tmp_dumpman$rannum 2>&1 & PID=$! sleep 0.1 running_check done echo $OPTION | grep "\ " >& /dev/null if [ $? = 0 ]; then MAXTIMEOUT=$(eval cat $SYSMANDIR/$APP/{`echo $OPTION|sed 's/\ /,/g'`} | grep TIMEOUT= | awk -F "\"" '{print $2}' | sort -nr | head -1) elif [ $? = 1 ]; then MAXTIMEOUT=$(eval cat $SYSMANDIR/$APP/`echo $OPTION` | grep TIMEOUT= | awk -F "\"" '{print $2}' | sort -nr | head -1) fi PROGCOUNT=$MAXTIMEOUT PROGSLEEP=0.8 progress_bar LOGCHK=$(lsof -t `echo $SYSMANDIR/$APP/tmp_dumpman$rannum` | wc -l) check_log_status INT=$(grep ^Dumping $SYSMANDIR/$APP/tmp_dumpman$rannum | awk -F ": " '{print $2}') LOG=$(grep ^Log $SYSMANDIR/$APP/tmp_dumpman$rannum | awk -F ": " '{print $2}') PROCLIST=$(echo $LOG | awk -F "-" '{print $2}') echo $INT if [ -z "$INT" ]; then RESULT="*덤프 실행에 문제가 발생했습니다.\n문제점: `sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" $SYSMANDIR/$APP/tmp_dumpman$rannum`" else RESULT="*덤프가 수행되었습니다.\n\n*실행정보: PID '$PID'로 '$INT'간 수행되었습니다.\n엔터를 누르면 상세 정보가 출력됩니다." fi echo $RESULT >> result_tmp"$rannum" } | whiptail --gauge "Getting data ..." 6 60 0 read -r result_tmp`` < result_tmp"$rannum" rm -f result_tmp"$rannum" whiptail --msgbox "$result_tmp" 10 70 whiptail --msgbox --scrolltext "$(cat "$SYSMANDIR/$APP/tmp_dumpman$rannum")" 30 120 rm -f $SYSMANDIR/$APP/tmp_dumpman$rannum return 0 #elif [ $RET = 1 ]; then # return 0 # echo $RET else exit ####### RET 변수에 대한 처리. 바로 전단계 do_dump 로 가지 못해 exit 처리 fi else whiptail --msgbox "* Check config files. Check, please." 12 60 return 0 fi else whiptail --msgbox "You are not root. You are $WHO\nCan be run only root." 20 60 1 fi } ## Funtion of do_loginhist ## function do_etc_loginhist { APP="apps/loginhist" CURTIME=`date +%Y%m%d" "%H -d "+1 hours"` PASTTIME=`date +%Y%m%d" "%H -d "-24 hours"` INPUTPERI=$(whiptail --inputbox "$PASTTIME $CURTIME -> 예시\n<아래는 '현재 -24시간' ~ '현재 +1시간'을 반영한 디폴트 기간입니다>\n<필요시 원하는 기간으로 수정 또는 그냥 진행하면 디폴트 기간이 반영됨>" 12 78 "$PASTTIME $CURTIME" --title "Input Period" 3>&1 1>&2 2>&3) RET6=$? if [ $RET6 = 0 ]; then IFS=' ' read -r -a array <<< "$INPUTPERI" STARTDATE=$(echo "$INPUTPERI" | awk '{print $1}' | awk -F "" '{print $5$6"/"$7$8"/"$1$2$3$4}') date -d "$STARTDATE" > /dev/null 2>&1 STARTDATE_VALID=$? STARTTIME=$(echo "$INPUTPERI" | awk '{print $2}') date "+%H" -d "$STARTTIME" > /dev/null 2>&1 STARTTIME_VALID=$? ENDDATE=$(echo "$INPUTPERI" | awk '{print $3}' | awk -F "" '{print $5$6"/"$7$8"/"$1$2$3$4}') date -d "$ENDDATE" > /dev/null 2>&1 ENDDATE_VALID=$? ENDTIME=$(echo "$INPUTPERI" | awk '{print $4}') date "+%H" -d "$ENDTIME" > /dev/null 2>&1 ENDTIME_VALID=$? STIME=$(echo "$INPUTPERI" | awk '{print $1$2}') ETIME=$(echo "$INPUTPERI" | awk '{print $3$4}') if [ ! ${#array[@]} = 4 ]; then whiptail --msgbox "* 요구되는 포맷에 맞지 않게 입력했습니다.\n아래와 같이 4개의 값을 입력하세요.\n$PASTTIME $CURTIME" 10 60 do_etc_loginhist elif [ $STARTDATE_VALID = 1 ] || [ $STARTTIME_VALID = 1 ] || [ $ENDDATE_VALID = 1 ] || [ $ENDTIME_VALID = 1 ] ; then whiptail --msgbox "* 정상 범위를 벗어난 시간을 입력했습니다.\n입력값: $INPUTPERI" 10 60 do_etc_loginhist elif [ $STIME -gt $ETIME ]; then whiptail --msgbox "* 기간이 잘 못 되었습니다. 끝 시간이 시작보다 과거임." 10 60 do_etc_loginhist else $SYSMANDIR/$APP/loginhist.sh $INPUTPERI & { progress_bar LOGCHK=$(lsof -t `echo $SYSMANDIR/logs/loginhist_log/loginhist.result` | wc -l) check_log_status } | whiptail --gauge "Getting data ..." 6 60 0 whiptail --msgbox --scrolltext "로그: $SYSMANDIR/logs/loginhist_log/loginhist.result\n$(cat "$SYSMANDIR/logs/loginhist_log/loginhist.result")" 40 130 #whiptail --msgbox "* $INPUTPERI 기간의 history 로그를 기록하였습니다.\n로그파일: $SYSMANDIR/logs/loginhist_log/loginhist.result" 10 60 do_etc fi else do_etc fi } #do_monitor_logmaker () { #while true #do # read -ra confs <<< $(ls $SYSMANDIR/apps/logmaker/*.conf | awk '{print $NF}' | awk -F "/" '{print $NF; print $NF}') # OPTION=$(whiptail --title Networking --menu "Select a config." 16 78 5 "${confs[@]}" 3>&1 1>&2 2>&3) # RET=$? # if [ $RET = 0 ]; then # #let OPTION=$OPTION-1 # randomcount # echo "Running option:" $OPTION # $SYSMANDIR/apps/logmaker/logmaker.sh "--conf=$OPTION" # else # exit # fi #done #} ## Funtion of do_tor_logmakerdump_tcp ## #function do_dump_tcp { # { # { # $SYSMANDIR/apps/tcpdump/do_dump_tcp.sh # } 1>/dev/null 2>&1 # source <(grep '^LOGFILE=' $SYSMANDIR/apps/tcpdump/do_dump_tcp.sh) # RESULT="Create tcpdump log: $LOGFILE" # echo $RESULT > result_tmp"$rannum" # progress_bar # } | whiptail --gauge "Getting data ..." 6 60 50 #} ###### Functions End ###### ###### Interactive use loop Start ###### if [ "$INTERACTIVE" = True ]; then calc_wt_size while [ 1 ] do CHOICE=$(whiptail --title "<Systems Manager>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT \ "L" "Log - <<Log Manager>>" \ "D" "Dump - <<Dump Manager>>" \ "E" "ETC - <<ETC Manager>>" \ "Q" "QUIT - <<Quit Manager>>" \ 3>&2 2>&1 1>&3) RET=$? if [ $RET -eq 1 ]; then exit elif [ $RET -eq 0 ]; then case $CHOICE in "L") do_monitor ;; "D") do_dump ;; "E") do_etc ;; "Q") exit ;; esac else exit 1 fi done fi ###### Interactive use loop End ######
SysMan(System Manager) script