반응형
작성일: 2023년 9월

 

IP address 범위를 지정하여 ping 패킷(즉, ICMP Echo Request)를 보내고 싶다면, 아래 예제 스크립트처럼 작성하여 실행하면 된다.

 

#!/usr/bin/bash

for ip in $(seq 1 7);
  do ping -c 1 10.1.4.$ip;
done

 

반응형

 


 

작성일: 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: 나중에 추가로 예제를 작성하기

##

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

반응형

아래 Script는 Kuberentes Node의 IP Address를 얻어와서, 이 IP Address로 Node에 SSH 접속하여 'shutdown' 명령을 수행하는 예제이다.

 

#!/bin/bash

for ip in $(oc get nodes  -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}')
do
   echo "reboot node $ip"
   ssh -o StrictHostKeyChecking=no core@$ip sudo shutdown -r -t 3
done
반응형

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
반응형

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

 

 

 

반응형

들어가는 말

Kubernetes 명령 도구인 'kubectl'을 사용하다보면, 수많은 타이핑 때문에 손가락이 아프고, 전체 명령어를 다 외울 수 없어서 명령을 입력하다가 주저하는 경우가 있다.

이럴 때, kubectl bash auto-completion 기능을 활용하면 명령어 입력하는 것이 한결 쉬워진다.

kubectl의 auto-completion 기능에 대해서 설명한 Web docs는 많은데, 대부분 Ubuntu, CentOS 환경에서 사용하는 것을 가정하고 설명하다보니, Mac에서 Web docs의 설명과 같이 따라해보면 안 된다.

 

Bash 버전부터 업그레이드

2021년 현재 macOS에 기본 설치된 Bash는 v3.2이다. 이 Bash를 v4.1+으로 Upgrade해야 한다.

주의: Bash v3.2로는 kubectl auto-completion을 사용할 수 없다

MacOS에서 Bash를 upgrade하는 절차는 아래 Web docs에 잘 설명되어 있으므로, 이 순서를 따른다.

Upgrading Bash on macOS

 

위 Web docs를 명령만 요약해보면 이렇다.

##
## brew 명령으로 bash를 설치한다.
##
$  brew install bash
...
...

$  which -a bash
/usr/local/bin/bash
/bin/bash

$  /usr/local/bin/bash --version
GNU bash, version 5.1.8(1)-release (x86_64-apple-darwin20.3.0)
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

##
## /etc/shells에 '/usr/local/bin/bash'를 추가한다.
##
$  sudo vim /etc/shells
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/usr/local/bin/bash       ## 이 라인을 추가한다.

##
## Set default shell
##
$  chsh -s /usr/local/bin/bash

## TODO: 위 chsh 명령을 수행한 후에
##       반드시 기존 iTerm2 터미널을 종료하고, 새로운 iTerm2 터미널을 열어야 
##       새로운 버전의 bash 명령을 사용할 수 있다.

$  echo $BASH_VERSION
5.1.8(1)-release

 

Bash auto-completion

MacOS에 설치된 Bash가 v4.1+ 인 것을 확인했다면, 아래 Web docs를 따라서 설정해주면 모든 것이 끝!

bash auto-completion on macOS

위 Web Site의 Docs를 읽으면서, 아래 내가 작성한 문서를 비교하면서 작업해야 한다. 

위 Web Docs만 따라하면 bash 패키지 설치 디렉토리가 설치 대상 장비마다 달라서, 잘못된 설정을 하게 된다.

##
## 아래 문서를 따라서 설정할 때, 주의할 점이 있다.
## https://kubernetes.io/docs/tasks/tools/included/optional-kubectl-configs-bash-mac/
## 위 문서의 설명을 따라하다보면, bash-completion@2를 설치하고 나서, 
## .bash_profile에 바로 bash_completion.sh 정보를 작성하라고 되어 있는데
## 이때, Web Docs에 있는 것을 Copy & Paste하면 안 된다.
## 왜냐고?
## bash-completion@2가 minor 버전이 릴리즈될 때마다 설치 디렉토리가
##   - /usr/local/etc/... 인 경우가 있고,
##   - /opt/homebrew/...  인 경우가 있기 때문에
## Web Docs만 따라하면 제대로 설정할 수 없다.
## 따라서 아래 설치 명령의 제일 밑에 출력되는 내용을 copy해서 .bash_profile에 붙여 넣어야 한다.
## 즉, 결론적으로
## Kubernetes의 Web Docs는 전체 절차만 이해하는 수준으로 읽고,
## 아래 명령의 출력 결과에 나오는 안내 글을 읽고 따라서 설정 작업을 해야 잘 동작한다.
##

$  brew install bash-completion@2
... 중간 생략 ...

## 주의: 바로 이 안내 글을 꼭 주의깊게 읽고, .bash_profile 설정 작업을 해야 한다.

Add the following line to your ~/.bash_profile:
  [[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" ]] && . "/opt/homebrew/etc/profile.d/bash_completion.sh"
==> Summary
🍺  /opt/homebrew/Cellar/bash-completion@2/2.11: 753 files, 1MB
$

 

 

 

블로그 작성자: sejong.jeonjo@gmail.com

+ Recent posts