Shell Script

Table of Contents

curl

다양한 통신 프로토콜을 이용하여 데이터를 전송하기 위한 라이브러리와 명령 줄 도구

  • HTTPS 요청 with 인증서
▒ curl -HHost:httpbin.example.com --resolve httpbin.example.com:31390:192.168.0.99 --cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem https://httpbin.example.com:31390
  • 파일 다운로드
▒ curl -O https://cube.k3.acornsoft.io/download-cubectl
▒ curl -o download-cubectl.sh https://cube.k3.acornsoft.io/download-cubectl
  • 리모트 sh 파일 로컬 실행
▒ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.18.2 TARGET_ARCH=x86_64 sh -
  • 기타 사용법
▒ curl -s https://httpbin.org/headers -X GET                                     # http methods (GET,POST,PUT,DELETE)
▒ curl -s https://httpbin.org/headers -H "Header1:value1" -H "Header2:value2"    # add http header
▒ curl -s https://httpbin.org/headers -o /dev/null                               # output empty
▒ curl -s https://httpbin.org/headers -o /dev/null -w "code:%{http_code}";       # response code
▒ curl -i https://httpbin.org/ip                                                 # -i : print with http-headers

Standard IO

Variables

  • 특정 범위의 문자열 자르기 ${STR:offset:length}
▒ str="Hello, World, Bash"

▒ echo "${str:0:5}"
Hello

▒ echo "${str:7}"
World, Bash

▒ echo "${str:(-4)}"
Bash

▒ echo "${str:(-4):2}"
Ba
  • 첫번째 문자열 포함, 가장 짧게 매칭되는 문자열 삭제 : ${STR#PATTERN}
▒ str="AAABBBCCC"

▒ echo ${str#A*B}
BBCCC

▒ echo ${str#*B}
BBCCC

▒ echo ${str#B*C}
AAABBBCCC
▒ str1="/data/harbor"
▒ str2="data/harbor"

▒ echo ${str1#/} = ${str2#/}
data/harbor = data/harbor
  • 첫번째 문자열 포함, 가장 짧게 매칭되는 문자열 삭제 : ${STR##PATTERN}
▒ str="AAABBBCCC"

▒ echo ${str##A*B}
CCC

▒ echo ${str##*B}
CCC

▒ echo ${str##B*C}
AAABBBCCC
  • 마지막 문자열 포함, 가장 짧게 매칭되는 문자열 삭제 : ${STR%PATTERN}
▒ str="AAABBBCCC"

▒ echo ${str%A*B}
AAABBBCCC

▒ echo ${str%*B}
AAABBBCCC

▒ echo ${str%B*C}
AAABB
  • 마지막 문자열 포함, 가장 길게 매칭되는 문자열 삭제 : ${STR%%PATTERN}
▒ str="AAABBBCCC"

▒ echo ${str%%A*B}
AAABBBCCC

▒ echo ${str%%*B}
AAABBBCCC

▒ echo ${str%%B*C}
AAA
  • Null 이면 default 문자열 출력 ${STR:-value}
▒ str=""
▒ echo ${str:="default value"}
default value

▒ echo ${str}

  • Null 이면 default 문자열 출력 및 변수값 지정 ${STR:=value}
▒ str=""
▒ echo ${str:="default value"}
default value

▒ echo ${str}
default value

cut

파일 또는 표준입력 문자열을 바이트, 문자열, 필드 기준으로 문자열을 잘라 출력

  • cut -f1 -d ' ' : ‘ ‘ 로 구분 했을 때 첫번째 컬럼
▒ kubectl get secrets | grep default | cut -f1 -d ' '

awk

표준입력 문자열를 행과 단어 별로 처리해 출력

# 2행 1번째 컬럼 값 
▒ kubeadm token list | awk 'FNR==2 {print $1}'
▒ kubeadm token list | awk 'FNR==2 {print "token = " $1}'

# output 라인 갯수
▒ kubectl get nodes | awk 'END { print NR }'

# "foo"를 포함하지 않는 "message" 파일 출력
▒ cat message | awk '!/foo/'

sed

표준입력을 (행)추가, 변환, 제거 처리하여 출력

  • /etc/selinux/config 파일에서 SELINUX=disabledSELINUX=permissive 로 Replace.
▒ sed -i 's/SELINUX=disabled/SELINUX=permissive/' /etc/selinux/config
  • admin.conf 파일에서 server: 로 시작하는 행에서 server: (none) 행을 추가하고 5번행을 삭제해 출력한다.
▒ sed -e '/server:/i\server: (none)' -e '5d'  admin.conf
  • admin.conf 파일에서 5번행을 ` server: https://100.100.100.0:6443` 로 교체해서 출력
▒ sed '5s/.*/    server: https:\/\/100.100.100.0:6443/g' /etc/kubernetes/admin.conf
  • credentials 파일 2행에서 aws_secret_access_key = 문자열을 제거하고 출력
    ▒ head -n 2 credentials | tail -n 1 | sed  's/aws_secret_access_key = //g'
    
  • /etc/hosts 파일에서 127.0.0.1 로 시작 하는 행을 127.0.0.1 localhost itnp.kr 로 변경
▒ sed -i "s/127.0.0.1.*/127.0.0.1 localhost itnp.kr/g" /etc/hosts
  • 문자열 aaaabbbb 로 replace
▒ echo "aaaa.bbbb.cccc" | sed -e "s/aaaa/bbbb/g"

bbbb.bbbb.cccc
  • 큰따옴표를 제거 Replace - “"를 앞에 붙여줌
▒ echo "\"cb-cluster-w-xzuz4\"" | sed -e "s/\"//g"

cb-cluster-w-xzuz4

tee

표준입력을 표준출력 또는 파일에 쓰는 명령어

  • 파일에 행 추가
▒  echo "set \$l7 ${COMMAND};" | sudo tee -a /usr/local/nginx/conf/nginx-test.conf"

텍스트 파일 라인별 출력

  • 파일을 읽어 LF(line feed) 를 “\n” 로 전환한 문자열로 변환
# 방법 1
▒ while read line; do if [[ "$line" != "" ]]; then echo -n "$line\n";fi; done < aaa.txt

# 방법 2
▒ cat aaa.txt | while read line; do if [[ "$line" != "" ]]; then echo -n "$line\n";fi; done

ex

  • 예 : openssl.conf 파일에서 DNS.1 = localhost 찾아 DNS.2 = www.itnp.kr 라인을 추가
▒ ex openssl.conf <<EOF
/DNS.1 = localhost/ 
:append
DNS.2 = www.itnp.kr
.
:x
EOF

텍스트 파일 생성

  • echo로 파일 만들기
▒  echo -e "[Interface]
Address = 10.66.66.1/24
ListenPort = 51820
PrivateKey = $(sudo wg genkey)" | sudo tee /etc/wireguard/wg0.conf
  • cat 으로 파일 생성 sudo
▒ sudo bash -c 'cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF'
  • 작은 따옴표안에서 작은 따옴표 문자열 사용 : \047
▒ echo -e 'kubectl get nodes --no-headers | awk \047END { print NR }\047'

kubectl get nodes --no-headers | awk 'END { print NR }'
  • sudo cat 으로 파일 생성
▒ sudo cat <<EOF> /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

for ~ in ~

▒ for IP in "192.168.122.20" "192.168.122.251"
do
  echo "@ $IP"
done
  • varables
    ▒ SERVERS='192.168.122.20 192.168.122.251'
    ▒ for IP in ${SERVERS}; do  echo "@ $IP"; done
    
  • carriage return
    ▒ SERVERS=$(printf "192.168.122.20\n192.168.122.251")
    ▒ for IP in ${SERVERS}; do  echo "@ $IP"; done
    
  • string split (delemeter)
    ▒ SERVERS=$(echo '192.168.122.20|192.168.122.251' | tr "|" "\n")
    ▒ for IP in ${SERVERS}; do  echo "@ $IP"; done
    

if

if [ expression ]; then
  <statement>
elif [ expression ]; then
  <statement>
else 
  <statement>
fi

if [ expression ]
then
  <statement>
else 
  <statement>
fi
  • Not
    if [ ! -f "$filename" ]
    fi
    
  • 비교 연산자
    • -z a : 문자열 길이가 0
    • -n a : 문자열 길이가 0 이상
    • a –eq b : a == b (equal)
    • a –ne b : a != b (negative)
    • a –gt b : a > b (greater then)
    • a –lt b : a < b (less then)
    • a –ge b : a >= b (greater or equal)
    • a –le b : a <= b (less or equal)
# 매개변수가 1보다 작으면
if [ $# -lt 1 ]; then
fi
  • 파일 검사

    • -e : Exist (노드, 디렉토리, 블록장치, 소켓 등)
    • -d : Directory
    • -f : File
    • -w : Writable
    • -x : Execuable
    • -r : Readable
    • -O : 소유자가 현재 사용자
    • -G : 소유자 그룹이 현재 사용자
    • -h : 심볼릭 링크
    • -b : 블록 디바이스
    • -S : 소켓 디바이스
    • -c : 캐릭터 장치 파일이면
    • -s : 0보다 큰 파일
    • a -nt b : a 가 b 보다 최신파일
    • a -ot b : a 가 b 보다 이전파일
    • a -ef b : a 와 b 가 같은 파일이

Use cases of Shell

key=value 파라메터

./credentials.sh aws="..." gcp="...."

for ARGUMENT in "$@"
do

    KEY=$(echo $ARGUMENT | cut -f1 -d=)
    VALUE=$(echo $ARGUMENT | cut -f2 -d=)   

    case "$KEY" in
            aws)        AWS_FILE=${VALUE} ;;
            gcp)        GCP_FILE=${VALUE} ;;
            azure)      AZURE_FILE=${VALUE} ;;
            alibaba)    ALIBABA_FILE=${VALUE} ;;
            tencent)    TENCENT_FILE=${VALUE} ;;
            oepnstack)  OPENSTACK_FILE=${VALUE} ;;
            *)   
    esac    


done

echo "AWS_FILE=${AWS_FILE}"

Passwordless and Sudoers

  • Passwordless
▒ USER="ubnutu"
▒ SERVERS='192.168.122.20 192.168.122.251'
▒ for IP in $SERVERS
do
  scp ${HOME}/cubectl-key.pub  ${USER}@${IP}:/home/${USER}/cubectl-key.pub
  ssh ${USER}@${IP} <<EOF
  cat /home/${USER}/cubectl-key.pub >> /home/${USER}/.ssh/authorized_keys
EOF
done
  • sudoers
▒ for IP in $SERVERS
do
  ssh -i ${HOME}/cubectl-key ${USER}@${SERVER_1} <<EOF
    echo "${USER} ALL=(ALL) NOPASSWD: ALL"  | sudo tee /etc/sudoers.d/${USER}-sudoer
EOF
done

sudo sh EOF

▒ cat <<EOF | sudo sh -x
apt-get install -y uidmap
EOF

Check for IP validity

▒ if [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  echo "is ip address"
else
  echo "fail"
fi

System Daemon

systemd

https://fmd1225.tistory.com/93

servaice 파일

  • Unit, Service, Install 섹션으로 구성
  • ExecStart : 실행 command
  • After : 이전에 실행할 서비스들, 나열된 서비스 이후에 실행 하겠다는 의미
  • Before: 이후에 실행할 서비스들, 나열된 서비스 이전에 실행 하겠다는 의미
▒ sudo bash -c 'cat > /lib/systemd/system/ladybug-bootstrap.service <<EOF
[Unit]
Description=Ladybug bootstrap script
After=multi-user.target
StartLimitIntervalSec=60
StartLimitBurst=3
[Service]
ExecStart=/lib/systemd/system/ladybug-bootstrap
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=kubelet.service
EOF'

# reload 및 reboot 시 실행하도록 지정
▒ sudo systemctl daemon-reload
▒ sudo systemctl enable ladybug-bootstrap
  • 조회
# unit 파일 리스트
▒ systemctl list-unit-files

# unit 파일 보기
▒ systemctl show kubelet.service

systemctl

# 실패 서비스 조회
▒ sudo systemctl --failed

# 동작중 서비스
▒ systemctl

# 의존관계 조회
▒ systemctl list-dependencies
▒ systemctl list-dependencies kubelet.service

# critical-chain
▒ systemd-analyze critical-chain
▒ systemd-analyze critical-chain kubelet.service


# 부팅과정에 각 서비스별 초기화하는데 걸린 시간
▒ systemd-analyze blame

# 부팅과정 svg 파일로 저장
▒ systemd-analyze plot > order.svg

# targe 조회
▒ systemctl list-units --type target --all

apt

  • Interactive command/화면 없이 패키지 설치
▒ sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install iptables-persistent
  • purge 설정파일도 함께 패키지 삭제, remove는 설정 파일은 유지하고 패키지 삭제
▒ sudo apt-get -y purge iptables-persistent

Kernel

▒ lsmod | grep 8021q  # 커널에서 vlan 모듈(8021q) 존재 확인
▒ modprobe 8021q      # 커널에 vlan 모듈(8021q) 추가

posted at 2022/03/18 09:42