섹션 8. 유용한 유틸리티

 

리눅스 서버를 자동화하여 관리하기 위한 쉘 스크립트(Shell Script) 심화 강좌를 정리합니다.
출처 : inflearn

1. 커맨드라인포토샵(imagemagick)

AWS_TEST:/home/shkim$ ls
bell.png
# convert imagemagick 의 대표 명령어
AWS_TEST:/home/shkim$ convert bell.png +dither -colors 10 -format "%C" histogram:info: | sed -n 's/^[]*\(.*\):.*[#]\([0-9a-fA-F]*\) .*$/#\2/p' | sort -r -n -k 1 -t "," | cut -c-7 > colors
AWS_TEST:/home/shkim$ cat colors # 색상정보가 출력된다.
#FF817D
#FF7E79
...
#7E01FD

# 원하는 색상 컬러로 변경하는 스크립트
# 읽어 드린 색상정보를 가지고 수정된 컬러이미지들을 만들어 내는 스크립트
AWS_TEST:/home/shkim$ while read color; do convert bell.png -fuzz 5% -fill black -opaque ${color} bell_${color}.png; done < colors

2. 명령어(nohup)

로그 아웃이나 터미널 종료 이후에도 명령이 데몬(Daemon)화 되어 계속 실행할 수 있게 도와주는 명령어

AWS_TEST:/home/shkim$ sleep 1000
^C
# 1>/dev/null : 표준 출력은 휴지통으로 들어감
# 2>&1 : 표준 오류는 표죽 출력으로 제어됨
# 0</dev/null : 표준 입력을 차단
# & : 백그라운드 프로세스화
AWS_TEST:/home/shkim$ date;nohup ./mydaemon.sh 1>/dev/null 2>&1 0</dev/null &
Thu Aug 13 04:34:24 PDT 2020
[1] 2907
AWS_TEST:/home/shkim$ exit
# 재접속
AWS_TEST:/home/shkim$ cat mydaemon.log
...
Thu Aug 13 04:35:23 PDT 2020

AWS_TEST:/home/shkim$ cat mydaemon.sh
#!/bin/bash

for i in {1..60};do
date >> mydaemon.log
sleep 1
done

3. 명령어(md5sum)

파일의 무결성 체크를 하는 스크립트 작성법 md5sum : 파일(데이터)의 무결성을 확인할 때 사용하는 md5의 유틸리티

AWS_TEST:/home/shkim$ cat helloworld.c
#include <stdio.h>

int main() {
    printf("hello world by C\n");
    return 0;
}
AWS_TEST:/home/shkim$ gcc -o helloworld helloworld.c # 컴파일
AWS_TEST:/home/shkim$ ./helloworld # 실행
hello world by C

AWS_TEST:/home/shkim$ tar cf helloworld.tar helloworld
AWS_TEST:/home/shkim$ md5sum helloworld.tar
60a9651bdc008b71c3571a0951305bfd helloworld.tar

AWS_TEST:/home/shkim$ vi helloworld_md5sum.sh #을 열어 위에서 나온 값을 대입해 준다.

#!/bin/bash
# Copyright (c) 2015 guileschool.com
# All rights reserved.
#
# NAME:  helloworld.sh
# VER:   1.0.0
# PLAT:  linux
# DESCR: tutorial of md5sum 
# BYTES: 222326344
# LINES: 48
# MD5:   60a9651bdc008b71c3571a0951305bfd
# NOTE: inspired by Anaconda2-2.4.1-MacOSX-x86_64.sh 

THIS_DIR=$(cd $(dirname $0); pwd)
THIS_FILE=$(basename $0)
THIS_PATH="$THIS_DIR/$THIS_FILE"
PREFIX=$THIS_DIR #$HOME/anaconda2
BATCH=0
FORCE=0

# verify the MD5 sum of the tarball appended to this header
MD5=$(tail -n +48 "$THIS_PATH" | md5sum)
echo $MD5 | grep 60a9651bdc008b71c3571a0951305bfd >/dev/null
if (( $? )); then
    echo "WARNING: md5sum mismatch of tar archive
expected: 60a9651bdc008b71c3571a0951305bfd
     got: $MD5" >&2
fi

# extract the tarball appended to this header, this creates the *.tar.bz2 files
# for all the packages which get installed below
# NOTE:
#   When extracting as root, tar will by default restore ownership of
#   extracted files, unless --no-same-owner is used, which will give
#   ownership to root himself.
cd $PREFIX

tail -n +48 "$THIS_PATH" | tar xf - --no-same-owner
if (( $? )); then
    echo "ERROR: could not extract tar starting at line 48" >&2
    exit 1
fi

${THIS_DIR}/helloworld

exit 0


# 파일 병합(설치스크립트 생성) => helloworld.sh = helloworld_md5sum.sh(text) + helloworld.tar(binary)
AWS_TEST:/home/shkim$ cat helloworld_md5sum.sh helloworld.tar > helloworld.sh
AWS_TEST:/home/shkim$ ./helloworld.sh
hello world by C

실행만 하면 동일한 스크립트라고 생각될 수 있으나, 파일의 무결성을 점검하여 무결성이 확인되지 않으면 설치를 못하게 하는 스크립트 입니다.

4. 명령어(tee)

표준출력이나 표준에러 출력을 보면서 동시에 로그파일을 남기게 할 경우

# tee : 리눅스 화면과 파일에 동시에 출력하기
AWS_TEST:/home/shkim$ echo "Jurassic World" | tee steven.txt #overworte
Jurassic World
AWS_TEST:/home/shkim$ cat steven.txt
Jurassic World

AWS_TEST:/home/shkim$ echo "Jurassic World" | tee -a steven.txt #append
Jurassic World
AWS_TEST:/home/shkim$ cat steven.txt
Jurassic World
Jurassic World

AWS_TEST:/home/shkim$ grep -i "Star Wars" steven.txt lucas.txt 2>&1 | tee george.txt #error
grep: lucas.txt: No such file or directory
AWS_TEST:/home/shkim$ cat george.txt
grep: lucas.txt: No such file or directory

5. 히어독(HEREDOC)

# << : HERE DOCUMENT 연산자
SHKIM:/home/shkim/edu$ sed 's/hello/goodbye/' <<HERE
> hello world
> hello world
> HERE # 앞쪽에 공백문자나 탭문자가 있으면 안됨. 관행적으로 대문자를 이용하여 HERE 외 다른 글자도 무방
goodbye world
goodbye world
SHKIM:/home/shkim/edu$  ssh user@192.168.16.213 <<'HERE' # local 서버(테스트용)
> uname -r #현재 리눅스 시스템의 커널 버전을 확인하는 명령어.
> exit
> HERE

5.10.157-139.675.amzn2.aarch64
SHKIM:/home/shkim/edu$ 

(아래)간단히 요약해 보자면 HERE DOCUMENT 가 변수 확장을 하고 사용되는가, 그냥 사용되는가의 차이이다.

AWS_TEST:/home/shkim/edu$ pwd
/AWS_TEST:/home/shkim/edu
AWS_TEST:/home/shkim/edu$ ssh user@192.168.16.213 <<HERE #인용부호 없이 사용
> echo PWD is ${PWD}
> exit
> HERE
PWD is /home/shkim/edu
AWS_TEST:/home/shkim$ ssh user@192.168.16.213 <<'HERE'
> echo PWD is ${PWD}
> HERE
PWD is /home/shkim
AWS_TEST:/home/shkim$ ssh user@192.168.16.213 <<'HERE' > log
> echo PWD is ${PWD}
> exit
> HERE
AWS_TEST:/home/shkim$ cat log
PWD is /home/shkim

6. 사례분석

사용자에게 사용방법이나 정보를 제공해주는 HEREDOC 만드는 방법(함수)

SHKIM:/home/shkim$ usage() {
> cat <<HEREDOC
> Installs Anaconda2 2.4.1
> 
>     -b    run install in batch mode (without manual intervention),
>           it is expected the license terms are agreed upon
>     -f    no error if install prefix already exists
>     -h    print this help message and exit
>     -p PREFIX    install prefix, defaults to
> HEREDOC
> }

SHKIM:/home/shkim$ usage
Installs Anaconda2 2.4.1

    -b    run install in batch mode (without manual intervention),
          it is expected the license terms are agreed upon
    -f    no error if install prefix already exists
    -h    print this help message and exit
    -p PREFIX    install prefix, defaults to
SHKIM:/home/shkim$ 

7. 히어스트링(HERESTRING)

# <<< : HERE STRING 연산자
# sed 에는 파일의 형태로 전달됨.
SHKIM:/home/shkim$ sed 's/hello/goodbye/' <<< 'hello world'
goodbye world
SHKIM:/home/shkim$ IFS=$',' read -r c1 c2 c3 c4 <<< "france,russia,UK,austria"
SHKIM:/home/shkim$ printf "%s %s %s %s\n" "$c4" "$c3" "#c2" "$c1" 
austria UK #c2 france

8. 명령어(uniq)

텍스트 파일 내에 중복된 내용의 행이 연속으로 있으면 중복없이 하나의 행으로 만들어 주는 명령어

SHKIM:/home/shkim/edu$ cat fruits_multi.txt 
apple
apple
apple
apple
strawberry
strawberry
orange

SHKIM:/home/shkim/edu$ uniq fruits_multi.txt 
apple
strawberry
orange

SHKIM:/home/shkim/edu$ uniq -c fruits_multi.txt 
      4 apple
      2 strawberry
      1 orange

SHKIM:/home/shkim/edu$ uniq -d fruits_multi.txt 
apple
strawberry

9. 명령어(sort)

SHKIM:/home/shkim/edu$ cat fruits.txt 
grapes
orange
tomato
strawberry
apple

SHKIM:/home/shkim/edu$ sort fruits.txt 
apple
grapes
orange
strawberry
tomato

sort 옵션 h을 이용하면 2k,300M,1G등과 같이 사람이 읽을 수 있는 숫자를 정렬하고 비교할 수 있습니다

SHKIM:/home/shkim$ du -h | sort -h
0	./edu/b
0	./edu/b/test1
0	./edu/b/test1/.test
0	./edu/b/test2
0	./edu/b/test2/.test
0	./edu/db_backup/data/20210305
0	./edu/db_backup/log
0	./edu/shell_cmd/images_mirror
0	./edu/shell_cmd/mydir2
4.0K	./edu/shell_cmd/images
4.0K	./edu/shell_cmd/images/drill
8.0K	./.ssh
8.0K	./edu/db_backup/data
8.0K	./edu/db_backup/data/20210304
8.0K	./edu/dir1
20K	./edu/shell_cmd/quiz
28K	./edu/db_backup
40K	./edu/a
40K	./edu/shell_cmd/md5sum
148K	./edu/shell_cmd/csv
224K	./edu/shell_cmd/imagemagick
4.6M	./edu/shell_cmd/image4
5.3M	./edu/shell_cmd
5.4M	./edu
18M	.
SHKIM:/home/shkim$

# 역순
SHKIM:/home/shkim/edu$ sort  -r fruits.txt 
tomato
strawberry
orange
grapes
apple

# : 를 구분자로 3번째 필드를 정렬하여 보여 줌
SHKIM:/home/shkim/edu$ sort -n -t$':' -k3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
unbound:x:992:988:Unbound DNS resolver:/etc/unbound:/sbin/nologin
sphinx:x:993:989:Sphinx Search:/usr/lib/tmpfiles.d/lib/sphinx:/bin/bash
nginx:x:994:990:Nginx web server:/var/lib/nginx:/sbin/nologin
epmd:x:995:991:Erlang Port Mapper Daemon:/tmp:/sbin/nologin
ec2-instance-connect:x:996:994::/home/ec2-instance-connect:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
rngd:x:998:996:Random Number Generator Daemon:/var/lib/rngd:/sbin/nologin
libstoragemgmt:x:999:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
ec2-user:x:1000:1000:EC2 Default User:/home/ec2-user:/bin/bash
shkim:x:1001:1001::/home/shkim:/bin/bash
test:x:1002:1002::/home/test:/bin/bash
ssm-user:x:1003:1003::/home/ssm-user:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin