반응형

 


 

작성일: 2024년 2월 21일

 

Shell script 작성할 때마다 책꽂이 어딘가에 있을 책을 찾는 것이 귀찮고, 인터넷에서 검색하는 것도 귀찮아서, 
내가 자주 사용하는 Shell script use case를 정리하는 것이 편하겠다는 생각이 들었다.

 

 

Bash Shell Programming 추천 문서

추천 문서 1

  • Link: https://www.lesstif.com/lpt/bash-shell-script-programming-26083916.html
  • 이 문서가 다루는 내용
    • For loop
    • Script parameter, argument ($0, $1, ... $n, $@)   // CLI를 통해서 받은 argument를 처리하는 방법
    • getopt
    • compare operator (비교 연산자, if then fi, else, elif, ... )
    • File test (디렉토리 존재 여부, 파일 존재 여부, 실행 파일 여부 등 검사)
    • String test (문자열이 공백인지 검사,  Regular expression 정규식)
    • File 읽기 (Text file을 line by line으로 읽어서 변수에 담기)
    • nohup + stdin/out redirect (스크립트를 background로 실행시켜 terminal이 끊길 때 스크립트가 종료되는 것을 방지)
    • EUID 활용법 (일반 계정, root 계정으로 실행했는지 테스트)
    • $? 변수 체크 (외부 명령을 실행 후, 그 결과가 성공/실패인지를 체크)

추천 문서 2

  • Link: https://velog.io/@markyang92/declaretypeset
  • 이 문서가 다루는 내용
    • 변수 이름 작명 규칙
    • 변수 선언, 변수 사용(값 참조)
    • eval 키워드 사용법
    • export, declear, set 키워드를 사용하는 이유 및 활용 사례
    • unset, typeset 키워드 사용 사례
    • 미리 정의된 환경 변수 (HOME, PATH, LANG, SHELL, USER, DISPLAY, PS1, PS2, LINES, LS_COLORS 등)

추천 문서 3

  • Link: https://blog.gaerae.com/2015/01/bash-hello-world.html
  • 이 문서가 다루는 내용
    • function 선언, function 참조
    • 변수 선언, 변수 사용(값 참조)
    • 예약 변수(Reserved Variable): FUNCNAME, SECONDS, SHLVL, PPID, BASH_ENV, BASH_VERSION, OSTYPE
    • 위치 매개 변수(Positional Parameters): $0,  $1,  $*,  $@,  $#
    • 특수 매개 변수(Special Parameters): $$,  $?,  $!,  $-,  $_
    • 매개 변수 확장(Parameter Expansion): ${변수:-단어}  ${변수#단어}  ${변수/%찾는단어/변경단어}
    • 배열 변수(Array Variable): ${array[3]}  ${array[@]}
    • 변수 타입 지정(Variables Revisited): declare, typeset
    • 논리 연산자(Logical Operator):  &&  -a   ||  -o
    • 산술 연산자(Arithmetic Operator):  **  +=  -=  *=  /= %=
    • 비트 연산자(Bitwise Operator):  <<   <<=  >>=  &   &=  |   |=  ~   ~  ^   ^=
    • 정수 비교(Integer Comparison):  -eq  -ne  >  -gt  >=  -ge  <  -lt  <=  -le
    • 문자열 비교(String Comparision):  =  ==  !=  <  >  -z   -n
    • 파일 비교 연산자(File Test Operator):  -e  -f  -s  -d -b  -c  -p  -nt  -ot  -ef
    • 반복문: for  while  until
    • 조건문:  if elif  else  fi
    • 선택문:  case ... esac
    • 디버깅 방법: Dry run (bash -n my-run.sh)

 


 

유용한 스크립트 예제 모음

 

Remote node의 파일을 가져와서 Local node의 파일과 동일한지 확인 후 Local 장비에 반영하거나 삭제

아래 스크립트에서 유용한 부분은

  • date(날짜) 출력 포맷을 가공
  • 여러 단어(Word)로 구성된 문자열을 cut 명령으로 자르기(cut, split, delimiter)
  • if 조건문 사용
#!/usr/bin/bash

MY_REMOTE_ACCT=my-id@my-domain.kr

CUR_DATE=`date +%+4Y-%m-%d-%H-%M-%S`
ORIGIN_FILE="my-domain.kr.zone"
REMOTE_FILE="${ORIGIN_FILE}_remote"
BACKUP_FILE="${ORIGIN_FILE}_${CUR_DATE}_bkup"
DIR_PATH=/var/cache/bind

cd $DIR_PATH

scp ${MY_REMOTE_ACCT}:${DIR_PATH}/${ORIGIN_FILE} $REMOTE_FILE

## cksum 명령의 결과가 3개의 컬럼으로 출력되는데, 
## 실제 필요한 데이터는 첫번째 column이라서 출력 내용을 cut -f 1 명령으로 잘라냄.
CKSUM_REMOTE_FILE=$(cksum $REMOTE_FILE | cut -d " " -f 1)
CKSUM_ORIGIN_FILE=$(cksum $ORIGIN_FILE | cut -d " " -f 1)

if [ $CKSUM_REMOTE_FILE -eq $CKSUM_ORIGIN_FILE ]; then
        echo "The ${CKSUM_REMOTE_FILE} and the $CKSUM_ORIGIN_FILE are equivalent"
        exit 1
fi

echo "The ${CKSUM_REMOTE_FILE} and the $CKSUM_ORIGIN_FILE are different"

cp $ORIGIN_FILE $BACKUP_FILE
cp $REMOTE_FILE $ORIGIN_FILE

systemctl restart bind9

 

 

##

## TODO: 나중에 추가로 예제를 작성하기

##

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

반응형

 

가끔 쉘 프로그래밍을 하다보면, 문자열의 큰 따옴표를 떼어내야 할 경우가 있다.

아래 예제처럼 작성하면 따옴표를 제거할 수 있다.

 

##
## APP_NAME이 "myapp"과 같이 따옴표가 앞 뒤에 포함되어 있다고 가정하자.
## 문자열 시작, 끝에 붙여 있는 따옴표를 떼려면 아래와 같이 sed 명령으로 변경할 수 있다.
## 

APP_NAME=$(sed -e 's/^"//' -e 's/"$//' <<< $APP_NAME)

 

반응형

Macbook을 새로 구입하고, .bash_profile을 작성할 때 참고하려고 작성했다.

 

#
# Greeting message
#   31 Red
#   32 Green
#   33 Yellow
#   34 Blue
#   35 Magenta
#   36 Cyan
#   Reference: https://en.wikipedia.org/wiki/ANSI_escape_code
#


# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# For Ubuntu, CentOS
#OS_DESCRIPTION=$(lsb_release -d)
# For Mac OS
OS_DESCRIPTION=$(uname -srn)

echo "                                                "
echo "  Bourne Again Shell  Environment  for  Andrew "
echo "  $OS_DESCRIPTION "
echo "                                                "

#
# For core dumped file
#
ulimit -c unlimited

#
# Locale
#
## LC_CTYPE=ko_KR.utf8
export LC_ALL="en_US.UTF-8"
export LANGUAGE="en_US.UTF-8"

# export VIM=/usr/share/vim/vim74
export PATH=$PATH:/sbin:/usr/sbin:/usr/local/go/bin:./
export PATH=$PATH:/usr/local/Cellar/iftop/1.0pre4/sbin
export PATH=$PATH:$HOME/go/bin
export PATH=$PATH:$HOME/bin

ssh2() {
    ssh  -oStrictHostKeyChecking=no  -p 33322  $@
}

sftp2() {
    sftp  -oStrictHostKeyChecking=no  -P 33322  $@
}

mandump() {
    man $1 | col -bx > man_page_$1.txt
}

## For docker monitoring
docker_ip() {
    sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$@"
}

mywhile() {
	while true; do date;  $2;  echo "";  echo "";  sleep $1;  done
}

conn_vpn() {
	sudo  openconnect --protocol=gp $1
}

## For Mac OS
get_cpu_mac() {
    # istats all
    istats cpu
}

## For Raspberry PI
get_cpu_pi() {
    my_cpu_temp=$(vcgencmd measure_temp)
    echo " *** Execute vcgencmd *** "
    echo "  + CPU Temperature : $my_cpu_temp "

    echo ""
    echo " *** Get information from /sys/class/thermal/thermal_zone0/temp *** "
    cpu=$(</sys/class/thermal/thermal_zone0/temp)
    echo "  + CPU Temperature : $((cpu/1000)) c "
}

## Kubernetes
kube_andrew() {
  export KUBECONFIG=~/Documents/kube_config/andrew
  kubectl config get-contexts
}

kube_peter() {
  export KUBECONFIG=~/Documents/kube_config/peter
  kubectl config get-contexts
}

## For Mac OS
export PS1="\h:\w > "


export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
source <(kubectl completion bash)
alias k=kubectl
complete -F __start_kubectl k

alias ls='ls -FG'

## For Mac OS
# defaults write .GlobalPreferences com.apple.mouse.scaling -23000
# efaults write -g com.apple.mouse.scaling 5

 

 

'Ubuntu' 카테고리의 다른 글

Install BIND for name server(DNS) on Ubuntu 22.04  (0) 2021.11.05
openssl command example  (0) 2021.11.04
.vimrc 작성  (0) 2021.07.22
iptables and netfilter  (1) 2021.07.10
tcpdump로 HTTP Packet Decode 하기 및 tshark 사용법  (0) 2021.07.10
반응형

man 명령으로 man page를 읽으면, 위/아래 페이지 이동이나 검색하는 것이 불편하다.

차라리 text 파일을 열어서 검색하는 것이 앞/뒤 문맥을 확인하기 편하고, 전체 페이지 중에서 내가 어디쯤을 읽고 있는지 감을 잡기도 편하다.

그래서 이런 불편함을 해결하려고 man page를 text file로 dump하는 것을 만들었다.

 

##
## Filename:  .bash_profile  또는  .bashrc
##

mandump() {
    man $1 | col -bx > man_page_$1.txt
}

 

위와 같이 .bashrc 파일에 명령 'mandump'를 추가하고,  아래와 같이 실행한다.

$ mandump curl

$ vi man_page_curl.txt

curl(1)                           Curl Manual                          curl(1)
NAME
       curl - transfer a URL

SYNOPSIS
       curl [options / URLs]
       
DESCRIPTION
       curl  is  a tool to transfer data from or to a server, using one of the
       supported protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS,  IMAP,
       IMAPS,  LDAP,  LDAPS,  POP3,  POP3S,  RTMP, RTSP, SCP, SFTP, SMB, SMBS,
       SMTP, SMTPS, TELNET and TFTP). The command is designed to work  without
       user interaction.
 ...
 ...

 

 

 

 

반응형

Shell script를 작성하다보면, Random 숫자가 필요한 경우가 있다.

아래 예제 스크립트처럼 $RANDOM 변수를 사용하면, 매번 새로운 random integer를 구할 수 있다.

 

 

간단한 Example Script

#!/usr/local/bin/bash

for i in `seq 3`
do
    myrand=$RANDOM
    echo "Original random number: $myrand"

    mynum=$(expr $myrand / 1000)
    echo "Devided number: $mynum"
done

 

 

Random 초 만큼 쉬면서 CURL 명령을 반복 수행하는 Example Script

아래 예제는 실제로 ISTIO의 BookInfo 예제를 돌릴 때, 내가 종종 이용하는 Script이다.

 

#!/bin/bash

test_url="http://node-40.hub.cncf/productpage"

for i in $(seq 1 99999)
do
    curl -s -o /dev/null $test_url -: \
         -s -o /dev/null http://grafana.hub.cncf/?orgId=1 -:   \
         -s -o /dev/null http://tracing.hub.cncf/jaeger/search

    myrand=$RANDOM
    mysleeptime=$(expr $myrand % 7)
    printf "Run count: %d    (Sleep: %d seconds)\r" $i $mysleeptime
    sleep $mysleeptime
done
반응형
#!/usr/local/bin/bash

for i in $(seq 1 99)
do
    printf "Run count: %d \r" $i
    ## To do something at this line.
    sleep 0.5
done

Shell script로 for loop을 돌리면서, 'echo' 또는 'printf' 명령을 사용할 때 화면 아래로 text가 쭉 출력된다.

단순하게 count 값이 증가되는 것을 출력하는 것이라면, 아래로 쭉 내려가는 것보다는 같은 자리에서 counter 숫자만 갱신되는 것이 훨씬 예쁘다.

방법은 간단하다. C언어에서 사용한 것처럼 Carriage Return을 사용하면, 같은 자리에서 증분되는 counter만 출력할 수 있다.

 

아래 예제처럼 작성하고 돌려보시라 :D

 

 

 

+ Recent posts