실무에서 자주 사용되는 쉘 스크립트 #5
(트래픽 점검(측정) 유틸리티)
지난강좌(#4)는 ping을 이용하여 여러 서버를 점검하는 스크립트를 만들어 보았다.
금번 강좌에서는 서버의 트래픽을 간단하게 확인 할 수 있는 트래픽 측정 유틸리티를 만들어 보도록 하겠다. 우리가 흔히 얘기하는 트래픽은 초당 얼마나 많은 데이터들이 소통되는지를 의미한다. 트래픽의 단위는 대부분 Bit/Sec로 표현한다. 원하는 목표를 달성해 보자^^
항상 그렇듯 차근 차근 문제를 풀어 보도록 하자 ...
1) 트래픽 정보를 어디에서 구할 수 있을까?
트래픽을 측정하기 위해서는 어디에서 정보를 구해와야 한다.
트래픽.... 그렇다면 네트웍 장치와 관련이 있을 것이며, 그 정보를 /proc 에서 찾을 수 있었다.
물론 .. ifconfig 명령어를 입력하면 찾을 수 도 있다.
(1) /proc의 트래픽 관련 정보 수집
cat /proc/net/dev
결과 :
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo:85543370 1148565 0 0 0 0 0 0 85543370 1148565 0 0 0 0 0 0
eth0:1829471133618 19299120632 0 0 0 0 0 1498386 14446844326628 21830048151 0 0 0 0 0 0
eth1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
위 정보가 복잡해 보이지만, 많은 정보를 내포하고 있다.
네트웍 장치가 여러개 보이지만, eth0, eth1 이 주요 측정 대상이 되며, 숫자가 많이 적힌 eth0이 주 인터페이스인 것을 확인 할 수 있다.
(2) 위 정보에서 eth1에 대한 정보만 수집하자.
grep eth0 /proc/net/dev
결과 :
eth0:1829520748902 19299665416 0 0 0 0 0 1498445 14446945435248 21830514044 0 0 0 0 0 0
원하는 정보를 추출 하였다. 각 값들은 여러가지 의미를 내포하지만, 우리에게 필요한 것은 인터페이스를 통해 전달된(송/수신)데이터 양이다. 1번째숫자(수신)와, 9번째 숫자(송신)만 필요하다.
(3) 원하는 값만 뽑아 내자 (awk)
grep eth0 /proc/net/dev | awk '{print $1}'
결과 :
eth0:1829578744769
첫번째 값을 뽑아 내었다. 이 값은 인터페이스가 수신한 데이터 양이다.
여기서 사용한 awk 명령어는 아주 아주 유용한 명령어이다. ㅤㅅㅞㅂ 스크립트를 작성하는데 꼭! 꼭! 필요한 명령이며 아주 많은 기능을 가지고 있다. 위 예제에서 사용한 것은 표준 입력값을 받아서 첫번째($1) 단어만 추출한 것이다. 물론 공백을 기준으로 단어를 나누게 된다.
그런데! 앞에 장치명(eth0)이 붙은 것을 확인할 수 있다.. 제거해야 하는데..
(4) "eth0:"를 제거해 보자 (sed)
grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'
결과 :
1829619555710
eth0: 를 제거했다.
그런데 sed 는 무엇이고 그 다음에 나오는 것은 무엇일까???
sed는 스트림에디터 이다. 표준 입력으로 들어오는 내용을 편집 하는 것이다.
"s/.*:// :" s/표현1/표현2/ 를 의미하며 표현1을 표현2로 바꾸겠다는 것이다.
".*:" "."은 아무 글자를 의미하고, "*"는 0개 이상을 의미한다.
결론적으로 ":" 앞에 아무글자가 오는 것을 모두 지우라는 의미이다.
그렇다면 생각해 보자.
eth0:232312
에서 eth0는 : 앞에 오는 0개 이상의 아무 글자이다 그래서 제거하면,
232312 가 된다.^^
(5) 뽑아낸 정보로 트래픽을 계산해 보자
rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
sleep 3
rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
rx3=$((rx2-rx1))
echo "$rx3"
결과 :
352273
rx1을 조사하고 3초간 기다린다. 기다리게 하기 위해 sleep 명령어를 사용하였다.
3초후 rx2를 조사했다. 그런다음 rx2에서 rx1을 뺐다.
bash 쉘에서 숫자 계산을 하기 위해서는 $((계산식)) 을 사용한다!! 계산식에 변수는 $를 붙이지 않는다.
위 계산 결과는 3초 동안의 트래픽 변화양이다. 그리고 그 단위는 Byte 이다.
(6) KBit/Sec 단위로 변환해 보자
rx3=$(( (rx2-rx1)/3*8/1024 ))
위 계산식에서 3초간 조사했기에 3으로 나눴고,
Byte를 Bit로 바꾸기 위해 8을 곱하고, Bit를 KBit로 바꾸기 위해서 1024로 나눴다.
이미 계산할 수 있는 것은 계산하여 컴퓨터의 부하를 줄여보자.
x*8/1024 = x*128 이 된다.
그렇다면 계산식은
rx3=$(( (rx2-rx1)/3*128 ))
2) 3초간 트래픽을 측정할 수 있는 프로그램 완성!!
rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep eth0 /proc/net/dev | awk '{print $9}'`
sleep 3
rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep eth0 /proc/net/dev | awk '{print $9}'`
rx3=$(((rx2-rx1)/128/3))
tx3=$(((tx2-tx1)/128/3))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
위 스크립트는 rx(수신), tx(송신) 용량을 조사하여 3초간 기다린 다음 계산하여 보여주게 만들었다.
시간을 출력하기 위해 date 명령을 사용하였다.
'+%k:%M:%S' 는 시(24시) 분(60분) 초(60초)를 출력하기 위한 형식이다.
3) 계속 반복시키자
위와같이 작성하면 1번 실행하고 끝난다. #1번 강좌에서 배웠던 while 문을 이용하여 반복시켜 보겠다.
echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep eth0 /proc/net/dev | awk '{print $9}'`
sleep 3
rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep eth0 /proc/net/dev | awk '{print $9}'`
rx3=$(((rx2-rx1)/128/3))
tx3=$(((tx2-tx1)/128/3))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done
while 문을 사용하여 무한 반복하였다.!!
자 이렇게 하면 eth0의 트래픽을 3초간 조사하여 평균을 보여주는 프로그램을 완성하였다.!!
But!. 네트웍 장치가 eth0가 아닌 다른것이며? 3초 단위가 아닌 10초 단위로 보고 싶다면,... 그럴 때 마다 쉘 스크립트를 수정하기엔 너무 번거롭다.!!! 명령어 처럼 인자로 받아서 처리하고 싶은데......
4) 다양한 장치, 다양한 delay 시간 제공
프로그램이 인자를 받아서 처리 하는 것은 아주 당연한 일이다.. 쉘 스크립트와 같이 소스를 수정할 수 있으면 좋겠지만, 수정하지 못하는 컴파일된 명령어는 아주 힘든 일이다. 그럼 다음과 같이 처리해 보자!
echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
rx1=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep $1 /proc/net/dev | awk '{print $9}'`
sleep $2
rx2=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep $1 /proc/net/dev | awk '{print $9}'`
# 1024/8 == 128
rx3=$(((rx2-rx1)/128/$2))
tx3=$(((tx2-tx1)/128/$2))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done
a.sh 파일에 위와같이 입력하고 파일을 만든 다음. 실행권한을 주고 다음과 같이 실행한다.
./a.sh eth0 2
위와같이 입력하면, 인터페이스는 eth0를 사용하고 , delay 시간은 2초로 한 것이다.
위 쉘스크립트에서 첫번째 인자가 $1 (eth0) , 두번째 인자가 $2 (2) 인것이다.!!
5) 다른 사람들도 쓰게 하자!
'4)' 와 같이 작성하면, 명령어의 인자가 있다는 사실을 아는 사람은 작성한 사람 또는 쉘 스크립트를 본 사람만이 알 수 있다. 사람의 머리는 시간이 지나면 잊어 먹기 마련이다. 작성한 사람조차 뭘 넣어야 잘 작동할지 모른다. 다음과 같이 개선해 보자.
if [ "$1" == "" ] ; then
echo "사용법 : $0 장치명 [delay]"
echo "예) $0 eth0 3 "
exit 1
fi
if [ "$2" == "" ] ; then delay=3 ; else delay=$2 ; fi
echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
rx1=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep $1 /proc/net/dev | awk '{print $9}'`
sleep $delay
rx2=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep $1 /proc/net/dev | awk '{print $9}'`
# 1024/8 == 128
rx3=$(((rx2-rx1)/128/delay))
tx3=$(((tx2-tx1)/128/delay))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done
처음에 2번째 인자($2)를 조사하여 아무것도 없으면, 즉 입력이 되지 않았다면, 메시지를 뿌려준다.
$0는 실행한 프로그램 그 자체 파일명을 의미한다. exit 1는 리턴값 1을 반환하면서 종료하게 되는 것이다.
그리고 delay 시간은 있어도 되고 없어도 되게 하며, 기본값은 3으로 하였다.
3번째 인자($3)를 조사하여 없으면 $delay변수에 3을 넣고, 있으면 그 값을 넣어준다.
위 쉘스크립트를 이용하여 사용하고 서버의 트래픽을 점검 할 수 있다.
우리는 이것으로
아주 쉽게 트래픽을 확인 할 수 잇는 프로그램을 만들었다. 위 스크립트를 작성하면서 awk, grep, sed, sleep명령어 및 숫자 계산 $(()), 아규먼트 $1 , while, if, exit 문을 알게 되었다.
서버에 간단한 유틸리티를 깔아 놓음으로 트래픽을 바로 확인 할 수 있게 되었다. MRTG에서 그래프를 보려면 많이 기다려야 하는데.. 답답하지 않고 좋다^^ 넘넘 뿌듯하다^^..
(트래픽 점검(측정) 유틸리티)
지난강좌(#4)는 ping을 이용하여 여러 서버를 점검하는 스크립트를 만들어 보았다.
금번 강좌에서는 서버의 트래픽을 간단하게 확인 할 수 있는 트래픽 측정 유틸리티를 만들어 보도록 하겠다. 우리가 흔히 얘기하는 트래픽은 초당 얼마나 많은 데이터들이 소통되는지를 의미한다. 트래픽의 단위는 대부분 Bit/Sec로 표현한다. 원하는 목표를 달성해 보자^^
항상 그렇듯 차근 차근 문제를 풀어 보도록 하자 ...
1) 트래픽 정보를 어디에서 구할 수 있을까?
트래픽을 측정하기 위해서는 어디에서 정보를 구해와야 한다.
트래픽.... 그렇다면 네트웍 장치와 관련이 있을 것이며, 그 정보를 /proc 에서 찾을 수 있었다.
물론 .. ifconfig 명령어를 입력하면 찾을 수 도 있다.
(1) /proc의 트래픽 관련 정보 수집
cat /proc/net/dev
결과 :
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo:85543370 1148565 0 0 0 0 0 0 85543370 1148565 0 0 0 0 0 0
eth0:1829471133618 19299120632 0 0 0 0 0 1498386 14446844326628 21830048151 0 0 0 0 0 0
eth1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
위 정보가 복잡해 보이지만, 많은 정보를 내포하고 있다.
네트웍 장치가 여러개 보이지만, eth0, eth1 이 주요 측정 대상이 되며, 숫자가 많이 적힌 eth0이 주 인터페이스인 것을 확인 할 수 있다.
(2) 위 정보에서 eth1에 대한 정보만 수집하자.
grep eth0 /proc/net/dev
결과 :
eth0:1829520748902 19299665416 0 0 0 0 0 1498445 14446945435248 21830514044 0 0 0 0 0 0
원하는 정보를 추출 하였다. 각 값들은 여러가지 의미를 내포하지만, 우리에게 필요한 것은 인터페이스를 통해 전달된(송/수신)데이터 양이다. 1번째숫자(수신)와, 9번째 숫자(송신)만 필요하다.
(3) 원하는 값만 뽑아 내자 (awk)
grep eth0 /proc/net/dev | awk '{print $1}'
결과 :
eth0:1829578744769
첫번째 값을 뽑아 내었다. 이 값은 인터페이스가 수신한 데이터 양이다.
여기서 사용한 awk 명령어는 아주 아주 유용한 명령어이다. ㅤㅅㅞㅂ 스크립트를 작성하는데 꼭! 꼭! 필요한 명령이며 아주 많은 기능을 가지고 있다. 위 예제에서 사용한 것은 표준 입력값을 받아서 첫번째($1) 단어만 추출한 것이다. 물론 공백을 기준으로 단어를 나누게 된다.
그런데! 앞에 장치명(eth0)이 붙은 것을 확인할 수 있다.. 제거해야 하는데..
(4) "eth0:"를 제거해 보자 (sed)
grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'
결과 :
1829619555710
eth0: 를 제거했다.
그런데 sed 는 무엇이고 그 다음에 나오는 것은 무엇일까???
sed는 스트림에디터 이다. 표준 입력으로 들어오는 내용을 편집 하는 것이다.
"s/.*:// :" s/표현1/표현2/ 를 의미하며 표현1을 표현2로 바꾸겠다는 것이다.
".*:" "."은 아무 글자를 의미하고, "*"는 0개 이상을 의미한다.
결론적으로 ":" 앞에 아무글자가 오는 것을 모두 지우라는 의미이다.
그렇다면 생각해 보자.
eth0:232312
에서 eth0는 : 앞에 오는 0개 이상의 아무 글자이다 그래서 제거하면,
232312 가 된다.^^
(5) 뽑아낸 정보로 트래픽을 계산해 보자
rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
sleep 3
rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
rx3=$((rx2-rx1))
echo "$rx3"
결과 :
352273
rx1을 조사하고 3초간 기다린다. 기다리게 하기 위해 sleep 명령어를 사용하였다.
3초후 rx2를 조사했다. 그런다음 rx2에서 rx1을 뺐다.
bash 쉘에서 숫자 계산을 하기 위해서는 $((계산식)) 을 사용한다!! 계산식에 변수는 $를 붙이지 않는다.
위 계산 결과는 3초 동안의 트래픽 변화양이다. 그리고 그 단위는 Byte 이다.
(6) KBit/Sec 단위로 변환해 보자
rx3=$(( (rx2-rx1)/3*8/1024 ))
위 계산식에서 3초간 조사했기에 3으로 나눴고,
Byte를 Bit로 바꾸기 위해 8을 곱하고, Bit를 KBit로 바꾸기 위해서 1024로 나눴다.
이미 계산할 수 있는 것은 계산하여 컴퓨터의 부하를 줄여보자.
x*8/1024 = x*128 이 된다.
그렇다면 계산식은
rx3=$(( (rx2-rx1)/3*128 ))
2) 3초간 트래픽을 측정할 수 있는 프로그램 완성!!
rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep eth0 /proc/net/dev | awk '{print $9}'`
sleep 3
rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep eth0 /proc/net/dev | awk '{print $9}'`
rx3=$(((rx2-rx1)/128/3))
tx3=$(((tx2-tx1)/128/3))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
위 스크립트는 rx(수신), tx(송신) 용량을 조사하여 3초간 기다린 다음 계산하여 보여주게 만들었다.
시간을 출력하기 위해 date 명령을 사용하였다.
'+%k:%M:%S' 는 시(24시) 분(60분) 초(60초)를 출력하기 위한 형식이다.
3) 계속 반복시키자
위와같이 작성하면 1번 실행하고 끝난다. #1번 강좌에서 배웠던 while 문을 이용하여 반복시켜 보겠다.
echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep eth0 /proc/net/dev | awk '{print $9}'`
sleep 3
rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep eth0 /proc/net/dev | awk '{print $9}'`
rx3=$(((rx2-rx1)/128/3))
tx3=$(((tx2-tx1)/128/3))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done
while 문을 사용하여 무한 반복하였다.!!
자 이렇게 하면 eth0의 트래픽을 3초간 조사하여 평균을 보여주는 프로그램을 완성하였다.!!
But!. 네트웍 장치가 eth0가 아닌 다른것이며? 3초 단위가 아닌 10초 단위로 보고 싶다면,... 그럴 때 마다 쉘 스크립트를 수정하기엔 너무 번거롭다.!!! 명령어 처럼 인자로 받아서 처리하고 싶은데......
4) 다양한 장치, 다양한 delay 시간 제공
프로그램이 인자를 받아서 처리 하는 것은 아주 당연한 일이다.. 쉘 스크립트와 같이 소스를 수정할 수 있으면 좋겠지만, 수정하지 못하는 컴파일된 명령어는 아주 힘든 일이다. 그럼 다음과 같이 처리해 보자!
echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
rx1=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep $1 /proc/net/dev | awk '{print $9}'`
sleep $2
rx2=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep $1 /proc/net/dev | awk '{print $9}'`
# 1024/8 == 128
rx3=$(((rx2-rx1)/128/$2))
tx3=$(((tx2-tx1)/128/$2))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done
a.sh 파일에 위와같이 입력하고 파일을 만든 다음. 실행권한을 주고 다음과 같이 실행한다.
./a.sh eth0 2
위와같이 입력하면, 인터페이스는 eth0를 사용하고 , delay 시간은 2초로 한 것이다.
위 쉘스크립트에서 첫번째 인자가 $1 (eth0) , 두번째 인자가 $2 (2) 인것이다.!!
5) 다른 사람들도 쓰게 하자!
'4)' 와 같이 작성하면, 명령어의 인자가 있다는 사실을 아는 사람은 작성한 사람 또는 쉘 스크립트를 본 사람만이 알 수 있다. 사람의 머리는 시간이 지나면 잊어 먹기 마련이다. 작성한 사람조차 뭘 넣어야 잘 작동할지 모른다. 다음과 같이 개선해 보자.
if [ "$1" == "" ] ; then
echo "사용법 : $0 장치명 [delay]"
echo "예) $0 eth0 3 "
exit 1
fi
if [ "$2" == "" ] ; then delay=3 ; else delay=$2 ; fi
echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
rx1=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx1=`grep $1 /proc/net/dev | awk '{print $9}'`
sleep $delay
rx2=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
tx2=`grep $1 /proc/net/dev | awk '{print $9}'`
# 1024/8 == 128
rx3=$(((rx2-rx1)/128/delay))
tx3=$(((tx2-tx1)/128/delay))
echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done
처음에 2번째 인자($2)를 조사하여 아무것도 없으면, 즉 입력이 되지 않았다면, 메시지를 뿌려준다.
$0는 실행한 프로그램 그 자체 파일명을 의미한다. exit 1는 리턴값 1을 반환하면서 종료하게 되는 것이다.
그리고 delay 시간은 있어도 되고 없어도 되게 하며, 기본값은 3으로 하였다.
3번째 인자($3)를 조사하여 없으면 $delay변수에 3을 넣고, 있으면 그 값을 넣어준다.
위 쉘스크립트를 이용하여 사용하고 서버의 트래픽을 점검 할 수 있다.
우리는 이것으로
아주 쉽게 트래픽을 확인 할 수 잇는 프로그램을 만들었다. 위 스크립트를 작성하면서 awk, grep, sed, sleep명령어 및 숫자 계산 $(()), 아규먼트 $1 , while, if, exit 문을 알게 되었다.
서버에 간단한 유틸리티를 깔아 놓음으로 트래픽을 바로 확인 할 수 있게 되었다. MRTG에서 그래프를 보려면 많이 기다려야 하는데.. 답답하지 않고 좋다^^ 넘넘 뿌듯하다^^..
[출처] 실무에서 자주 사용되는 쉘 스크립트 #5|작성자 루루보이
'OS > LINUX' 카테고리의 다른 글
프로세스 - fork & exec (0) | 2011.05.14 |
---|---|
쉘 스크립트 #6 (0) | 2011.05.14 |
쉘스크립트 Ex4 (0) | 2011.05.14 |
쉘스크립트 Example2 (0) | 2011.05.14 |
쉘스크립트 example (0) | 2011.05.14 |