Showing posts with label bash. Show all posts
Showing posts with label bash. Show all posts

Wednesday, April 27, 2016

AnsiColor

ANSI Color 문법

----------------------------------------------------------------
ANSI 문법: {시작문자}{속성들}{색}{종료문자}
----------------------------------------------------------------
{시작문자}
        \e[

{속성들}
        0   속성없음
        1   도톰하게
        3   이탤릭체
        4   밑줄표시
        5   반짝이게
        7   색깔반전
        8   문자숨김
        9   문자취소선

{색}
        글자색
            30m 검정
            31m 빨강
            32m 초록
            33m 노랑
            34m 파랑
            35m 분홍
            36m 청록
            37m 하얀

        배경색
            40m 검정
            41m 빨강
            42m 초록
            43m 노랑
            44m 파랑
            45m 분홍
            46m 청록
            47m 하얀

        글자색 고강도
            90m 검정
            91m 빨강
            92m 초록
            93m 노랑
            94m 파랑
            95m 분홍
            96m 청록
            97m 하얀

        배경색 고강도
            100m    검정
            101m    빨강
            102m    초록
            103m    노랑
            104m    파랑
            105m    분홍
            106m    청록
            107m    하얀

{종료문자}
        \e[0m

----------------------------------------------------------------
ANSI 예제:
        echo -e "\e[31m빨강\e[0m"
        echo -e "\e[1;4;31m굵은밑줄빨강\e[0m"
----------------------------------------------------------------

ANSI Color 출력 예제

$ echo -e "\e[31m빨강\e[0m"
빨강

$ echo -e "\e[1;4;31m굵은밑줄빨강\e[0m"
굵은밑줄빨강

ANSI Color 출력 쉘스크립트

$ vi ansi_color.bash

#!/bin/bash
#

# ANSI 형식: {시작문자}{속성들}{색}{종료문자}
#
# {시작문자}:
#       \e[
# {속성들}:
#       0   속성없음
#       1   도톰하게
#       3   이탤릭체
#       4   밑줄표시
#       5   반짝이게
#       7   색깔반전
#       8   문자숨김
#       9   문자취소선
#
# {색}:
#       글자색
#           30m 검정
#           31m 빨강
#           32m 초록
#           33m 노랑
#           34m 파랑
#           35m 분홍
#           36m 청록
#           37m 하얀
#
#       배경색
#           40m 검정
#           41m 빨강
#           42m 초록
#           43m 노랑
#           44m 파랑
#           45m 분홍
#           46m 청록
#           47m 하얀
#
#       글자색 고강도
#           90m 검정
#           91m 빨강
#           92m 초록
#           93m 노랑
#           94m 파랑
#           95m 분홍
#           96m 청록
#           97m 하얀
#
#       배경색 고강도
#           100m    검정
#           101m    빨강
#           102m    초록
#           103m    노랑
#           104m    파랑
#           105m    분홍
#           106m    청록
#           107m    하얀
#
# {종료문자}:
#       \e[0m
#
# ANSI 예제:
#       echo -e "\e[31m빨강\e[0m"
#       echo -e "\e[1;4;31m굵은밑줄빨강\e[0m"

normal=0
bold=1
italic=2
underline=3
blink=4
reverse=5
concealed=6
escline=7
color=8
bg_color=9

black=10
red=11
green=12
yellow=13
blue=14
purple=15
cyan=16
white=17

_NAME[black]='검정'
_NAME[red]='빨강'
_NAME[green]='초록'
_NAME[yellow]='노랑'
_NAME[blue]='파랑'
_NAME[purple]='분홍'
_NAME[cyan]='청록'
_NAME[white]='하얀'

# ANSI 접두사
_ANSI_ON='\e['

# ANSI 초기화
_ANSI_OFF='\e[0m'

# 문자 일반
_ANSI_ATTR[normal]='0'

# 문자 도톰
_ANSI_ATTR[bold]='1'

# 문자 이탤릭채
_ANSI_ATTR[italic]='3'

# 문자 밑줄
_ANSI_ATTR[underline]='4'

# 문자 반짝
_ANSI_ATTR[blink]='5'

# 문자색 반전(글자색/배경색 서로 바꿈)
_ANSI_ATTR[reverse]='7'

# 문자 숨김
_ANSI_ATTR[concealed]='8'

# 문자 취소선
_ANSI_ATTR[escline]='9'

# 문자 도톰 제거
_ANSI_RM[bold]='22m'

# 문자 이탤릭체 제거
_ANSI_RM[italic]='23m'

# 문자 밑줄 제거
_ANSI_RM[underline]='24m'

# 문자 반전(글자색/배경색) 제거
_ANSI_RM[reverse]='27m'

# 문자 취소선 제거
_ANSI_RM[escline]='29m'

# 문자 색깔 제거
_ANSI_RM[color]='39m'

# 문자 배경색 제거
_ANSI_RM[bg_color]='49m'

# 글자색을 지정
_ANSI_COLOR[black]='30m'            # 검정
_ANSI_COLOR[red]='31m'              # 빨강
_ANSI_COLOR[green]='32m'            # 초록
_ANSI_COLOR[yellow]='33m'           # 노랑
_ANSI_COLOR[blue]='34m'             # 파랑
_ANSI_COLOR[purple]='35m'           # 분홍
_ANSI_COLOR[cyan]='36m'             # 청록
_ANSI_COLOR[white]='37m'            # 하얀

# 배경색을 지정
_ANSI_COLOR_BG[black]='40m'         # 검정
_ANSI_COLOR_BG[red]='41m'           # 빨강
_ANSI_COLOR_BG[green]='42m'         # 초록
_ANSI_COLOR_BG[yellow]='43m'        # 노랑
_ANSI_COLOR_BG[blue]='44m'          # 파랑
_ANSI_COLOR_BG[purple]='45m'        # 분홍
_ANSI_COLOR_BG[cyan]='46m'          # 청록
_ANSI_COLOR_BG[white]='47m'         # 하얀

# 글자색을 고강도로 지정(High Intensity)
_ANSI_COLOR_HI[black]='90m'         # 검정
_ANSI_COLOR_HI[red]='91m'           # 빨강
_ANSI_COLOR_HI[green]='92m'         # 초록
_ANSI_COLOR_HI[yellow]='93m'        # 노랑
_ANSI_COLOR_HI[blue]='94m'          # 파랑
_ANSI_COLOR_HI[purple]='95m'        # 분홍
_ANSI_COLOR_HI[cyan]='96m'          # 청록
_ANSI_COLOR_HI[white]='97m'         # 하얀

# 배경색을 고강도로 지정(High Intensity)
_ANSI_COLOR_HI_BG[black]='100m'     # 검정
_ANSI_COLOR_HI_BG[red]='101m'       # 빨강
_ANSI_COLOR_HI_BG[green]='102m'     # 초록
_ANSI_COLOR_HI_BG[yellow]='103m'    # 노랑
_ANSI_COLOR_HI_BG[blue]='104m'      # 파랑
_ANSI_COLOR_HI_BG[purple]='105m'    # 분홍
_ANSI_COLOR_HI_BG[cyan]='106m'      # 청록
_ANSI_COLOR_HI_BG[white]='107m'     # 하얀

# 일반적인 글자색 출력
for color in black red green yellow blue purple cyan white
do
    echo -e -n "[${_ANSI_COLOR[color]}: ${_ANSI_ON}${_ANSI_COLOR[color]}${_NAME[color]}${_ANSI_OFF}] "
done
echo

# 일반적인 배경색 출력
for color in black red green yellow blue purple cyan white
do
    echo -e -n "[${_ANSI_COLOR_BG[color]}: ${_ANSI_ON}${_ANSI_COLOR_BG[color]}${_NAME[color]}${_ANSI_OFF}] "
done
echo

# 속성별 글자 출력
for color in black red green yellow blue purple cyan white
do
    for attr in bold italic underline blink reverse concealed escline
    do
        echo -e -n "[${_ANSI_ATTR[attr]};${_ANSI_COLOR[color]}: ${_ANSI_ON}${_ANSI_ATTR[attr]};${_ANSI_COLOR[color]}${_NAME[color]}${_ANSI_OFF}] "
    done
    echo
done

$ bash ansi_color.bash

enter image description here

기타

vi에서 ANSI 쓰기

$ vi ansi.txt

^[[0;31m빨강^[[0m

$ cat ansi.txt
빨강

vi 에서 \e 쓰기(”’^[”’)

입력모드(i) -> Ctrl + v + ESC



BashExamples

파일 확장자 바꾸기

현재 디렉토리에 있는 파일중에서 txt 확장자를 php 로 변경 하는 ShellScript

$ vi change_extension.sh

#! /bin/env bash
#
# extname to toname
extname="txt"
toname="php"
for i in $(echo *.${extname})
do
    prefix=${i%%.${extname}};
    [ -f "$i" ] && mv $i $prefix.${toname}
done

해쉬 구현

$ vi bash_hash.sh

#! /bin/env bash

hash_insert () {
    local name=$1 key=$2 val=$3
    eval __hash_${name}_${key}=$val
}

hash_find () {
    local name=$1 key=$2
    local var=__hash_${name}_${key}
    echo ${!var}
}

hash_insert mh k1 one
hash_insert mh k2 two
hash_insert mh k3 three

hash_find mh k1
hash_find mh k2
hash_find mh k3

$ bash bash_hash.sh

one
two
three

Nginx worker_cpu_affinity 설정

CPU 개수별로 worker 할당 출력 스크립트

$ vi nginx_affinity.sh

#! /bin/env bash
#
# Linux only.
# Nginx worker_cpu_affinity
# http://wiki.nginx.org/CoreModule

n=$(awk '/^processor/{n=$3} END{print n}' /proc/cpuinfo)
aff=$(printf "0%0${n}d" 0)
printf "worker_processes %d\n;" $((n+1))
[ $n -eq 0 ] && exit;
printf "worker_cpu_affinity "
for ((a=0; a <= n; a++))
do
    poss=$((n - a))
    pose=$((n - poss))
    if [ $pose -eq 0 ]; then
        printf "%0${poss}d1" 0
    elif [ $poss -eq 0 ]; then
        [ $poss -eq 0 ] && printf "1%0${pose}d" 0
    else
        [ $pose -ne 0 ] && printf "%0${poss}d1%0${pose}d" 0 0
    fi

    [ $n != $a ] && echo -n " " || echo ";";
done

$ bash nginx_affinity.sh

 worker_processes 16;
 worker_cpu_affinity 0000000000000001 0000000000000010 0000000000000100 0000000000001000 0000000000010000 0000000000100000 0000000001000000 0000000010000000 0000000100000000 0000001000000000 0000010000000000 0000100000000000 0001000000000000 0010000000000000 0100000000000000 1000000000000000;

worker 별 CPU 할당 확인(worker_cpu_affinity 미지정시: 0-15 로 할당)

$ ps aux | awk '/^(nginx|nobody).*nginx/ {cmd=sprintf("echo -n \"worker[%d] \";grep Cpus_allowed_list /proc/%d/status", $2, $2); system(cmd)}'

worker[20165] Cpus_allowed_list:        0
worker[20166] Cpus_allowed_list:        1
worker[20168] Cpus_allowed_list:        2
worker[20169] Cpus_allowed_list:        3
worker[20170] Cpus_allowed_list:        4
worker[20171] Cpus_allowed_list:        5
worker[20172] Cpus_allowed_list:        6
worker[20173] Cpus_allowed_list:        7
worker[20174] Cpus_allowed_list:        8
worker[20175] Cpus_allowed_list:        9
worker[20176] Cpus_allowed_list:        10
worker[20177] Cpus_allowed_list:        11
worker[20178] Cpus_allowed_list:        12
worker[20179] Cpus_allowed_list:        13
worker[20180] Cpus_allowed_list:        14
worker[20181] Cpus_allowed_list:        15

CPU 사용량 구하기

CPU usage - cpu0

$ vi cpu_usage.sh

#! /bin/env bash

wsec=3

# stat now
stat_n_f=/proc/stat

# stat old
stat_o_f=/var/tmp/stat_past

# snmp_pass_cpustat
snmp_n_f=/var/tmp/cpuusagelog.now

if [ -f "$stat_o_f" ];then
    jiff_b=($(awk '{print $1" "$2" "$3" "$4}' $stat_o_f))
else
    jiff_b=($(awk '/^cpu[[:space:]]/ {print $2" "$3" "$4" "$5}' $stat_n_f))
    sleep $wsec
fi

jiff_a=($(awk '/^cpu[[:space:]]/ {print $2" "$3" "$4" "$5}' $stat_n_f))

# User Jiffies
jiff[0]=$((jiff_a[0] - jiff_b[0]))

# Nice Jiffies
jiff[1]=$((jiff_a[1] - jiff_b[1]))

# System Jiffies
jiff[2]=$((jiff_a[2] - jiff_b[2]))

# Idle Jiffies
jiff[3]=$((jiff_a[3] - jiff_b[3]))

user=$(( jiff[0]*100 / (jiff[0] + jiff[1] + jiff[2] + jiff[3]) ))
nice=$(( jiff[1]*100 / (jiff[0] + jiff[1] + jiff[2] + jiff[3]) ))
system=$(( jiff[2]*100 / (jiff[0] + jiff[1] + jiff[2] + jiff[3]) ))
idle=$(( jiff[3]*100 / (jiff[0] + jiff[1] + jiff[2] + jiff[3]) ))
used=$((100-idle))

(( user > 100 || user < 0 )) && user=0;
(( nice > 100 || nice < 0 )) && nice=0;
(( system > 100 || system < 0 )) && system=0;
(( idle > 100 || idle < 0 )) && idle=0;
(( used > 100 || used < 0 )) && used=0;

printf "User: $user\nSystem: $system\nIdle: $idle\n" > $snmp_n_f

echo "User: $user%, Nice: $nice%, System: $system%, Idle: $idle%, Total Used: $used%"

if [ ! -e "$stat_o_f" -o -w "$stat_o_f" ];then
    echo "${jiff_a[0]} ${jiff_a[1]} ${jiff_a[2]} ${jiff_a[3]}" > $stat_o_f
else
    echo "WRITE ERROR: $stat_o_f"
fi

$ bash cpu_usage.sh

User: 0%, Nice: 0%, System: 0%, Idle: 99%, Total Used: 1%

Memory 사용률 구하기

Memory usage

$ vi mem_usage.sh

#! /bin/env bash

wsec=3
stat_f=/proc/meminfo

for ((a=1; a<((wsec**wsec)); a++))
do
        mem=($(awk '{printf $2" "}' $stat_f))
        use=$(( ((mem[0]-mem[1]-mem[2]-mem[3]) * 100) / mem[0] ))
        echo "used : $use%"
        sleep $wsec
done

$ sh mem_usage.sh

 used : 21%
 used : 24%

Traffic 사용률 구하기

Traffic usage - eth0

$ vi traffic_usage.sh

#! /bin/env bash

# http://en.wikipedia.org/wiki/Data_rate_units#kilobit_per_second

wsec=3
stat_f=/proc/net/dev
dev=eth0

for ((a=1; a<((wsec**wsec)); a++))
do
        traff_b=($(awk "/$dev/ { sub(/$dev:/, \"\"); print \$1\" \"\$9}" $stat_f))
        sleep $wsec
        traff_a=($(awk "/$dev/ { sub(/$dev:/, \"\"); print \$1\" \"\$9}" $stat_f))

        # In
        traff[0]=$((traff_a[0] - traff_b[0]))

        # Out
        traff[1]=$((traff_a[1] - traff_b[1]))

        IN=$(( (traff[0] * 8)/1000/$wsec ))
        OUT=$(( (traff[1] * 8)/1000/$wsec ))

        echo "IN  : $IN kbps"
        echo "OUT : $OUT kbps"
done

$ bash traffic_usage.sh

IN  : 5 kbps
OUT : 15 kbps
IN  : 59 kbps
OUT : 1228 kbps

Progress bar 구현

Using backspace

$ vi progress_backspace.sh

#! /bin/env bash

xs=( '/' '-' '|' )
xc=${#xs[@]}
for i in $(seq 1 100)
do
    x=$((i%xc))
    echo -n "[${xs[$x]}]"
    usleep 100000
    echo -en "\b\b\b"
done

$ bash progress_backspace.sh

[-]

Using ansicode

$ vi progress_ansicode.sh

#! /bin/env bash

xs=( '/' '-' '|' )
xc=${#xs[@]}
for i in $(seq 1 100)
do
    # Save Cursor Position
    echo -en "\e[s";

    x=$((i%xc))
    echo -n "[${xs[$x]}]"
    usleep 100000

    # Restores the cursor position
    echo -en "\e[u";
done

$ bash progress_ansicode.sh

[-]

조건문 단축(if else)

# 산술 증가
[ "$RET_VAL" == "0" ] && : $((_s++)) || : $((_f++))

변수 초기화

# v 의 값이 없다면 v에  "string" 할당
: ${v:=string}

# v 의 값이 없다면 v에  "string" 할당
v=${v:-string}

# _v 의 값이 없다면 v에 "string" 할당(_v 값은 치환되지 않음!)
v=${_v:-string}

함수 인자에 배열값 전달

$ vi function_args.sh

args_is_array() {
    local _args=("${!1}")
    local _c=${#_args[@]}
    for ((i=0; i < _c; i++))
    do 
        echo "arg$i: ${_args[$i]}"
    done

}

args=("one" "one two" "one two three")

args_is_array args[@]

$ bash function_args.sh

arg0: one
arg1: one two
arg2: one two three

파일의 모든 라인을 배열로 저장하기

$ vi file_to_array.sh

#! /bin/env bash
declare -a myarray
#readarray arr < file.txt # Include newline.
#readarray -t arr < file.txt # Exclude newline.
readarray -t arr <<EOF
one 1
two 2
three 3
four 4
five 5
EOF

ac=${#arr[@]}

for ((i=0; i < ac; i++))
do
    a=${arr[i]}
    echo "$i : $a"
done

$ bash file_to_array.sh

0 : one 1
1 : two 2
2 : three 3
3 : four 4
4 : five 5

socket 사용하기

$ vi tcp_socket.sh

#! /bin/env bash

# HTTP 질의 예제
max_open_files=$(ulimit -n)
host="google.com"
port="80"

# socket id 의 최대값은 max open files 와 동일(0부터)
socket=$(($RANDOM%$max_open_files))
connect="exec ${socket}<> /dev/tcp/$host/$port"
eval $connect
echo -en "GET /robots.txt HTTP/1.0\r\nConnection: close\r\n\r\n" >&${socket}
cat <&${socket}

$ bash tcp_socket.sh

User-agent: *
Disallow: /search
.
.

$ vi tcp_socket_scan.sh

#! /bin/env bash

# Port Scan 예제
host="google.com"
port="80"
(echo >/dev/tcp/$host/$port) &> /dev/null
[ "$?" == "0" ] && echo "open" || echo "closed"

$ bash tcp_socket_scan.sh

open

$ vi tcp_socket_scan_timeout.sh

#! /bin/env bash

# Port Scan 예제(Timeout 주기)
host="google.com"
port="31337"
timeout 1 bash -c "echo >/dev/tcp/$host/$port"  && echo "open" || echo "closed"

$ bash tcp_socket_scan_timeout.sh

closed