Wednesday, April 27, 2016

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


Post a Comment