줘이리의 인생적기

쉘 스크립트 본문

공부/시스템 프로그래밍

쉘 스크립트

줘이리 2021. 12. 27. 23:00
728x90

을 사용하여 프로그래밍 가능하다. (DevOps를 위해 기본적으로 익혀둘 필요 있음)

 

쉘 스크립트가 필요할 때는,

서버가 다운되어 확인해보니 로그파일을 업데이트할 저장공간이 남지 않아 프로그램이 비정상 종료되었다.

자동으로 오래된 로그파일을 삭제하는 쉘 스크립트를 생성하고 주기적으로 실행함으로써 서버가 다운되는 문제를 해결할 수 있다.

 

파일의 가장 첫 라인은 #!/bin/bash로 시작한다.

실행 권한을 가지고 있어야 하며, 일반적으로 .sh의 확장자를 가지고 있다.

 

사전에 정의된 지역변수를 알아보자.

$$ : 쉘의 프로세스 번호

$0 : 쉘스크립트 이름

$1 ~ $9 : 명령어의 해당 인수

$* : 쉘 이름 제외한 명령어의 모든 인수리스트

$# : 쉘 이름 제외한 인수의 개수

$? : 최근 실행한 명령어의 종료 값

   - 0 (성공), 1 ~ 125 (에러)

   - 126 (파일이 실행 가능하지 않음)

   - 128 ~ 255 (시그널 발생)

 


1. echo 예제

vi example.sh 라는 명령어로 아래와 같은 내용을 넣으면 echo를 사용할 수 있다.

(주석은 #을 사용한다.)

#!/bin/bash

# HELLO WORLD 출력
echo "HELLO WORLD"

 

2. 변수

변수 선언변수명=데이터 를 사용하며, 사이에 띄어쓰기는 사용하면 안 된다.

변수 사용$변수명 으로 사용한다.

#!/bin/bash

my_id='root'
my_dir='/etc/mysql'

echo $my_id $my_dir

 

3. 리스트 변수(배열)

리스트 변수 선언변수명=(데이터1 데이터2 데이터3 ...)

리스트 변수 사용${변수명[인덱스번호]}

 

#!/bin/bash

list=("111" "222" "333")
echo ${list[1]} # $list 배열의 두 번째 인덱스에 해당하는 222 출력
echo ${list[@]} # $list 배열의 모든 데이터 출력
echo ${list[*]} # $list 배열의 모든 데이터 출력
echo ${#list[@]} # 샾을 사용하여 $list 배열 크기 출력

filelist=( $(ls) ) # 해당 쉘스크립트 실행 디렉토리의 파일 리스트를 배열로 $filelist 변수에 입력
echo ${filelist[*]}

 

4. 연산자

expr을 사용하며, 역작은 따옴표(`) 를 사용해야 한다.

숫자마다 모두 한 칸씩 띄어 써야 한다.

+, -는 그냥 사용하며, *나, 괄호는 역슬래시(\)를 붙여 사용해야 한다.

#!/bin/bash

num=`expr \( 3 \* 5 \) / 4 + 7`
echo $num

 

5. 조건문

then과 fi 사이에 조건문 참일 때 명령문을 입력하며, 탭을 사용하여 가독성을 높일 수 있음(필수 X)

첫 번째 인자와 두 번째 인자를 받아 비교하는 예제를 작성해보겠다.

#!/bin/bash

if [ $1 != $2 ]
then
    echo "not the same"
    exit
fi

else 사용 시

#!/bin/bash

if [ $1 -eq $2 ]
then
    echo "same"
else
    echo "not the same"
fi

한 줄로 사용 시 

공백을 주의해야 하며, 세미콜론(;)을 사용한다.

#!/bin/bash

if [ $1 == $2 ]; then echo "SAME"; fi

 

 

5. for문

파이썬과 비슷하다. 예제로 알아보자

do와 done 사이에 명령어를 입력하면 된다.

#!/bin/bash

for database in $(ls)
do
    echo $database
done

ls로 뜨는 파일명들을 한줄로 출력해주는 반복문이다.

 

한줄로 사용 시

#!/bin/bash

for database in $(ls); do echo $database; done

 

6. while문

#!/bin/bash
lists=$(ls) # ls가 list로 들어감 
num=${#lists[@]} # list의 개수가 num으로
index=0

while [ $num -ge 0 ] # greater or equal
do
    echo ${lists[$index]}
    index=`expr $index + 1` # 다음 index
    num=`expr $num - 1` # 다음 num
done

문자 비교 구문

== : 일치 

!= : 일치하지 않음 

-z 문자 : 문자가 null이면 참

-n 문자 : 문자가 null이 아니면 참

 

수치 비교 구문

문자 -eq 문자 : equal

문자 -ne 문자 : not equal

문자 -lt 문자 : less than

문자 -le 문자 : less or equal

문자 -gt 문자 : greater than

문자 -ge 문자 : greater or equal

 

파일 검사 구문

-e 파일 : 파일 존재면 참

-d 파일 : 파일 디렉터리면 참

-h 파일 : 심볼릭 링크파일이면 참

-f 파일 : 일반파일이면 참

-r 파일 : 읽기 가능이면 참

-s 파일 : 파일 크기가 0이 아니면 참

-u 파일 : set-user-id가 설정되면 참

-w 파일 : 쓰기 가능 상태면 참

-x 파일 : 실행 가능 상태면 참

 

논리 연산 구문

조건1 -a 조건2 : and

조건1 -o 조건2 : or

조건1 && 조건2 : 양쪽 다 참

조건1 || 조건2 : 한쪽이라도 참

!조건 : not

true : 참

false : 거짓

 

을 사용하면 된다. 


현업 예제 1

 

인터넷 연결 안 될 때 게이트웨이 핑 확인

#!/bin/bash
ping ‑c 1 192.168.0.1 1> /dev/null

if [ #? == 0 ]
then
    echo "게이트웨이 ip주소 핑 성공"
else
    echo "게이트웨이 ip주소 핑 실패"
fi

ping : 핑 확인 명령어

-c 1 : 1번만 체크

192.169.0.1 : 게이트웨이 ip주소

1> /dev/null : 표준출력(1) 을 버려라

 


현업 예제 2

 

메모리 문제로 정기적으로 백업해야 할 상황일 때

#!/bin/bash

if [ -z $1 ]||[ -z $2 ] ; then # 첫번째 두번째 인자가 안들어온다면
	echo usage: $0 sourcedir targetdir # 쉘이름을 출력하며 인자를 제대로 적어달라고 출력
    
else
    SRCDIR=$1
    DSTDIR=$2
    BACKUPFILE=backup.$(data +%y%m%d%H%M%S).tar.gz #data라는 쉘명령어로 매번 다른 backup파일을 압축
    if [ -d $DSTDIR ]; then # 디렉토리 명이 있다면
        tar -cvzf $DSTDIR/$BACKUPFILE $SRCDIR # 압축
    else # 디렉토리 명이 없다면
        mkdir $DSTDIR # 디렉토리 생성 후 
        tar -cvzf $DSTDIR/$BACKUPFILE $SRCDIR # 압축
    fi
fi

현업 예제 3

 

로그파일 정리할 때

 

#!/bin/bash

LOGDIR=/var/log
GZIPDAY=1
DELDAY=2
cd $LOGDIR
echo "cd $LOGDIR"

# find 찾아라 . 현재 디렉토리에서 -type f 일반 파일 중 -name '*log.?' log관련된 파일
# -mtime +$GZIPDAY 1일 이상 경과된 -exec bash -c 압축해라
sudo find . -type f -name '*log.?' -mtime +$GZIPDAY -exec bash -c "gzip {}" \; 2> /dev/null
# -name '*.gz' 압축파일 중 -mtime +$DELDAY 2일 이상 경과된 -exec bash -c 삭제해라
sudo find . -type f -name '*.gz' -mtime +$DELDAY -exec bash -c "rm -f {}" \; 2> /dev/null

 

'공부 > 시스템 프로그래밍' 카테고리의 다른 글

mmap  (0) 2021.12.31
Pthread  (0) 2021.12.29
tar  (0) 2021.12.24
시그널(signal)  (0) 2021.12.22
프로세스 우선순위 변경  (0) 2021.12.20