쉘 스크립트

Sisyphus·2023년 1월 12일

  • 사용자와 커널 간 인터페이스 역할을 하는 프로그램
  • 명령, 옵션, 인자가 정확한지 확인하고 커널에 작업을 요청


쉘 스크립트

  • 텍스트 또는 프로그램
  • 리눅스/유닉스 쉘에 의해 실행되도록 설계된 프로그램


쉘 프로그래밍

  • 쉘의 내장된 기능 및 리눅스 명령들을 사용한 프로그램 만들기


쉘 스크립트 구조

#! 인터프리터(Interpreter) [옵션]	Ex) ! /bin/bash
#
# 주석(Comment)

함수명() {
	명령
    ...
}

변수1=값
변수2=# 주석(Comment)

쉘 문법(조건, 선택, 반복)
명령
...

# 주석(Comment)

함수 호출


Bash 쉘 초기화 파일

지역/환경 변수, 별칭, 함수, umask 값을 설정하기 위해 사용

System-wide

쉘을 사용하는 사용자 전체에게 영향을 미치는 파일

Ex) /etc/profile, /etc/bashrc

User Configuration

해당 사용자에게만 영향을 미치는 파일

Ex) $HOME/.bash_profile $HOME/.bashrc, $HOME/.bash_logout



변수

  • 지역 변수 : 쉘 프로세스안에서만 사용되는 변수
  • 환경 변수 : 자식 쉘 프로세스에 상속되어 사용될 수 있는 변수

variable=value

# !/bin/bash

echo -n "What is your name?\n"
read NAME
echo "Hello, $NAME"
❯ ./name.sh
What is your name?
❯ ./hello.sh
What is your name?
linux
Hello, linux


예약 변수

쉘에 의해 미리 정의된 변수


# !/bin/bash

# Bash Shell : Reserved Variables


echo "USER : $USER"
echo "HOME : $HOME"
echo "SHELL : $SHELL"
echo "PATH : $PATH"
echo "LANG : $LANG"
echo "PWD : $PWD"
echo "TERM : $TERM"
echo "HISTSIZE : $HISTSIZE"
echo "HISTFILE : $HISTFILE"
echo "PS1 : $PS1"
echo "PS2 : $PS2"
echo "PS3 : $PS3"
echo "PS4 : $PS4"
❯ ./rv.sh
USER :
HOME : /root
SHELL :
PATH : /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-11-openjdk-amd64/bin
LANG :
PWD : /root/scripts
TERM : xterm
HISTSIZE :
HISTFILE :
PS1 : #
PS2 : >
PS3 :
PS4 : +


함수(Functions)

함수명() {
	명령 1
    명령 2
    ...
}

# !/bin/bash

day() {
	date
	echo
	cal
}

day
❯ ./func.sh
Thu Jan 12 17:04:35 KST 2023

    January 2023
Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

# !/bin/bash

etcbp() {
	DATE=`date '+%Y%m%d'`		# DATE -> 오늘 날짜
	FILENAME="ETC_${DATE}.tar"	# FILENAME -> ETC_20230112.tar
    
    # 백업을 할지 물어봄
	echo -n "Do you wanna run the backup for /etc directory? (y|n) : "
    # 사용자로 부터 입력을받음
	read ANSWER	
    
    # 만약 입력이 y이면?
	if [ $ANSWER = y ]; then
    	# /backup 디렉터리가 없을 때
		if [ ! -d /backup ]; then
			mkdir /backup				# /backup 디렉터리를 만들고
		fi
		cd /etc							# /etc 디렉터리로 이동해서
		tar -cvf /backup/$FILENAME ./*	# 현재 디렉터리 백업
		cd ~							# 홈 디렉터리로 이동
        ls -l /backup					# /backup 디렉터리 출력
	fi
}

etcbp	# 함수 실행

❯ ./etcbp.sh
Do you wanna run the backup for /etc directory? (y|n) : y
.
.
.
.
./zsh/zshenv
./zsh/zlogout
./zsh/zshrc
./zsh/zlogin
./zsh_command_not_found
total 2872
-rw-r--r-- 1 root root 2938880 Jan 12 17:22 ETC_20230112.tar


비교 연산

  • 파일과 디렉터리 존재 유무 판단
  • 문자열 비교
  • 숫자 비교

test CONDITIONS 또는 [ CONDITIONS ]

파일과 디렉터리 존재 유무 판단


# !/bin/bash

echo -n "Enter a file or directory name : "
read FILENAME

if [ -f $FILENAME ]; then
	ls -l $FILENAME
elif [ -d $FILENAME ]; then
	ls -ld $FILENAME
else
	echo "file not found"
fi
root@6a2cde0b6160 ~/scripts
❯ ./test.sh
Enter a file or directory name : rv.sh
-rwxr-xr-x 1 root root 319 Jan 12 16:44 rv.sh

root@6a2cde0b6160 ~/scripts 6s
❯ ./test.sh
Enter a file or directory name : /root/scripts
drwxr-xr-x 2 root root 4096 Jan 12 17:39 /root/scripts

root@6a2cde0b6160 ~/scripts
❯ ./test.sh
Enter a file or directory name : 1111
file not found

문자열 비교


# !/bin/bash

echo -n "프로그램을 설치하겠습니까? ( yes | no ) : "
read ANS

if [ $ANS = yes ]; then
	echo "설치 완료"
elif [ $ANS = no ]; then
	echo "설치 실패"
else
	echo "잘못된 입력"
fi
root@6a2cde0b6160 ~/scripts
❯ ./test_str.sh
프로그램을 설치하겠습니까? ( yes | no ) : yes
설치 완료

root@6a2cde0b6160 ~/scripts
❯ ./test_str.sh
프로그램을 설치하겠습니까? ( yes | no ) : no
설치 실패

root@6a2cde0b6160 ~/scripts
❯ ./test_str.sh
프로그램을 설치하겠습니까? ( yes | no ) : a
잘못된 입력

숫자 비교


# !/bin/bash

echo "Input num1"
read NUM1

echo "Input num2"
read NUM2

if [ $NUM1 -eq $NUM2 ]; then
	echo "$NUM1 == $NUM2"

elif [ $NUM1 -gt $NUM2 ]; then
	echo "$NUM1 > $NUM2"
elif [ $NUM1 -lt $NUM2 ]; then
	echo "$NUM1 < $NUM2"
fi
❯ ./test_num.sh
Input num1
5
Input num2
10
5 < 10


산술 연산

  • expr : 정수에 대한 사칙 연산과 나머지 연산을 위해 사용
  • bc : 정수, 실수, 비교, 논리, 사인, 코사인, 탄젠트 등 계산도 가능

expr 정수 연산자 정수
expr 변수 연산자 정수

# !/bin/bash

echo "Input num1"
read NUM1

echo "Input num2"
read NUM2

RESULT=`expr $NUM1 + $NUM2`
echo "$NUM1 + $NUM2 = $RESULT"
RESULT=`expr $NUM1 - $NUM2`
echo "$NUM1 - $NUM2 = $RESULT"
RESULT=`expr $NUM1 \* $NUM2`
echo "$NUM1 * $NUM2 = $RESULT"
RESULT=`expr $NUM1 / $NUM2`
echo "$NUM1 / $NUM2 = $RESULT"
RESULT=`expr $NUM1 % $NUM2`
echo "$NUM1 % $NUM2 = $RESULT"
❯ ./expr.sh
Input num1
4
Input num2
2
4 + 2 = 6
4 - 2 = 2
4 * 2 = 8
4 / 2 = 2
4 % 2 = 0


If 문

if [조건]
	then
    명령문
fi
if [조건]
then
    명령문 1
elif [조건2]
then
	명령문 2
else
	명령문 3
fi

# !/bin/bash

echo "Input Number"
read NUM

RESULT = `expr $NUM % 2`

if [ $RESULT -eq 0 ];
then
	echo "짝수 입니다."
else
	echo "홀수 입니다."
fi
root@6d6f1c3bebce ~/scripts 6s
❯ ./if.sh
Input Number
3
홀수 입니다.

root@6d6f1c3bebce ~/scripts
❯ ./if.sh
Input Number
4
짝수 입니다.


for 문

for 변수 in 인자 1 인자 2 ...
do
	명령문
done

# !/bin/bash

list="A B C D E"

for l in $list
do
	echo $l
done
❯ ./for1.sh
A
B
C
D
E

0개의 댓글