Devops 도전기/linux

shell script 실습 정리

끝까지해봐야지 2021. 11. 1. 16:05

# mkdir ./script
[root@VM01 ~]# cd script/
[root@VM01 script]# vi ./cron_test1.sh

#!/bin/bash
echo "Cron Test" > /root/cron.txt -> :wq

[root@VM01 script]# chmod +x ./cron_test1.sh


- 별도의 컴파일과정이 필요 없다. x권한만 전부 주면 됨, 644 기본 허가권
  만약 root만 주고 싶으면 소유자에 권한에만 x 주면 됨

# ./cron_test1.sh : 그냥 이렇게만 쓰면 실행해주라는 뜻
그러면 root 하위에 cron.txt라는 문서 파일 생김
# cat /root/cron.txt
Cron Test -> 내용이 나오는걸 확인 가능



[쉘 스크립트 cron 예약 작업 과정]

# crontab -e : vi처럼 사용 가능
* * * * * /root/script/cron_test1.sh : 매일 모든 시간에 계속 실행하겠다.
48 9 * * * /root/script/cron_test1.sh : 매일 9시 48분에 실행하겠다.

# crontab -l : 작업했던 내용 출력
48 9 * * * /root/script/cron_test1.sh

# cat /var/spool/cron/root : 이 경로에 스크립트가 만들어짐
48 9 * * * /root/script/cron_test1.sh

# ls /root : 지정한 시간이 지나고 확인했을때 txt 파일이 있으면 성공!


#!/bin/bash
DATE=$(date +%Y-%m-%d) : 데이트 명령어를 추가해라. 2021-06-03 이렇게 -가 붙어서 출력 형식을 바꿔서 출력!
 %붙으면 그 자리에 있는 거만 뺴라

# tail -f /var/log/cron : 실시간 남는 로그기록에 대한 정보!

---------------------------------------------------------------------------------------------------

*Shell Script 연습


[test.sh] : 변수 사용 예제
- echo는 한 줄만 출력해주려고 한다.

#!/bin/bash
echo ""
echo "My Bash Path: $BASH"
echo "My Bash Version: $BASH_VERSION"
echo "My Bash PID: $BASHPID"
echo "My HostName: $HOSTNAME"
echo "Who am I: $USER"
echo "$USER Home Dir: $HOME"
echo "Working Dir: $PWD"
echo "Command Path: $PATH"
echo ""

echo "[Working Dirctory List]"
lst=$(ls -l)
printf "$s\n" "$lst" : 이렇게 하면 덩어리로 가져와서 라인 구분하여 출력해 줌
echo ""

echo "[Date Print]"
date=$(date)      : 시간 출력
echo $date
echo ""


[ arr.sh ] : 배열

#!/bin/bash
arr=("Um Mi Hee" "27" "Incheon")
echo ${#arr[@]} : 총데이터가 몇 개 들어있는지 출력해줌 #을 붙여줘야 개수 출력!
printf "val=%s\n" "${arr[@]}"

VAL[0]="TEST1"
VAL[1]="TEST2"
VAL[2]="TEST3"
echo ${VAL[0]}
echo ${VAL[1]}
echo ${VAL[2]}


[calc.sh] : 연산식 예제

#!/bin/bash
echo -n "Num1 Input: "
read num1
echo -n "Num2 Input: "
read num2

echo "Sum: `expr $num1 + $num2`"
echo "Sub: `expr $num1 - $num2`"
echo "Mul: `expr $num1 \* $num2`"
echo "Div: `expr $num1 / $num2`"
echo "Mod: `expr $num1 % $num2`"
echo "Ret: `expr \( $num1 + $num2 \) / $num1`"



[para.sh] : 파라미터값, 입력받은 값 예제

# ./para/sh "안녕 반가워 오랜만" : 이렇게 파라미터 값을 실행할 때 넣어야 한다.
- readonly : 변하지 않는 상수값을 지정하고 싶을 때 변수명 앞에 적어줌

#!/bin/bash
readonly text="Hello Shell Script"
echo $text

echo -n "Input Name, Age, Addr: "
read name age addr
printf "%s\n" "$name"
printf "%s\n" "$age"
printf "%s\n" "$addr"

echo "실행중인 스크립트 파일명: $0"
echo "첫 번째 인자 값: $1"
echo "두 번째 인자값: $2"
echo "세 번째 인자값: $3"
echo "모든 인자값 한 번에 출력: $*"


[if_test1.sh] : 조건식, 해당 파일이 있는지 없는지 확인하는 test

#!/bin/bash
echo -n "Enter Is command Path: "
read path
if [ -e $path ]; then
        echo "Is Command Execution file Location: $path"
elsd
        echo "Is Command Execution Not Found: $path"
fi


[if_test2.sh] : 0보다 큰지 작은지

#!/bin/bash
echo -n "Input Data: "
read a
if [ $a -gt 0 ]; then
        echo "$a is 0 More"
else
echo "$a is 0 Less"
fi



[if_test3.sh] : 중첩 if문, 입력한 수가 양수인지 음수인지

#!/bin/bash
echo -n "Input Data: "
read data
if [ $data -ge 0 ]; then
        if [ `expr $data % 2` -eq 0 ]; then : 여기서 홀 따옴표(') 아니라 쿼터!(`)
                echo "Data Positive Even Number"
        else
                echo "Data Positive Odd Number"
        fi
else
        echo "Input Data Negative Number"
fi


[if_tes4.sh] : 다중 if문, 평균과 합계를 구하고 시험 통과 여부 확인


#!/bin/bash
echo -n "Input Your Kor Score: "
read kor
echo -n "Input Your Eng Score: "
read eng
echo -n "Input Your Mat Score: "
read mat

sum=`expr $kor + $eng + $mat`
avg=`expr $sum / 3`

echo "Your kor Score: $kor"
echo "Your Eng Score: $eng"
echo "Your Mat Score: $mat"
echo "Your Sum Score: $sum"
echo "Your Avg Score: $avg"
echo ""

if [ $avg -lt 70 ]; then
        echo "Your Average Score: $avg Fail"
elif [ $kor -lt 60 ]; then
        echo "Your Kor Score: $kor Fail"
elif [ $eng -lt 60 ]; then
        echo "Your Eng Score: $eng Fail"
elif [ $mat -lt 60 ]; then
        echo "Your Mat Score: $mat Fail"
else
        echo "Passing The Exam"
fi


------------------------------------------------------------------------------------------

[Case문] : Select 문이랑 같이 쓰임, select 안 쪽에서 case문 처리

* Test1 

#!/bin/bash
echo "Select Menu"
echo "1.Sum"
echo "2.Sub"
echo "3.Mul"
echo "4.Div"
echo -n "Choice Number Input: "
read choice
echo -n "Calc Data Input(2): "
read num1 num2
case $choice in
        "1" )
                echo "Sum Data: `expr $num1 + $num2`";; : ';;' 2개로 닫아주기
        "2" )
                echo "Sub Data: `expr $num1 - $num2`";;
        "3" )
                echo "Mul Data: `expr $num1 \* $num2`";;
        "4" )
                echo "Div Data: `expr $num1 / $num2`";;
        * )
                echo "You Made a Wrong choice";;
esac


* Test 2

$1 : 파라미터값
#!/bin/bash
if [ -z $1 ]; then  : 여기서 스크립트 실행 시 값을 입력하면 else동작 아니면 if 동작!
        rental="Unknown Data"
else
        rental=$1
fi
case $rental in
        "car" )
                echo "$rental Rental Price: 40$";;
        "motorcycle" )
                echo "$rental Rental Price: 20$";;
        "bicycle" )
                echo "$rental Rental Price: 10$";;
        * )
                echo "$rental";;
esac



[Select문] : case문이랑 같이 사용됨, 메뉴 구성, 기본적으로 반복적으로 작동됨

#!/bin/bash
PS3="Please Enter Your Choice: "
option=("Coke" "Sprite" "Fanta")
select opt in "${option[@]}"
do
        case $opt in
                "Coke" )
                        echo "Coke Price 2000won";;
                "Sprite" )
                        echo "Sprite Price 1900won";;
                "Fanta" )
                        echo "Fanta Price 1500won";;
                * )
                        break;;
        esac
echo "Finished Any Key Enter"
done



[for 반복문]

* Test1

#!/bin/bash
lst='1 2 3 4 5 6 7 8 9'
for cnt in $lst
do
        echo -n $cnt
done
echo ""

- 실행하면 123456789 가 출력됨


* Test2

#!/bin/bash
for (( cnt=1;cnt<=10;cnt++ ))
do
        echo -n $cnt
done
echo ""

- 실행하면 12345678910 가 출력됨


* Test3

#!/bin/bash
for num in {1..10..2}
do
        echo $num
done

- 실행하면 
1
3
5
7
9
가 출력됨


* Test4

#!/bin/bash
arr=(itbank KG Kgitbank)
for name in ${arr[@]}
do
        echo $name
done


* Test5 (스크립트 다운 반복문)

#!/bin/bash
for file in $(ls /var/log/*.log) : 명령어 자체가 리스트가 되는 거고 그만큼 반복하겠다.
do
        echo "---- $file ----"
        head -1 $file
        echo ""
        echo ""
done


* Test6 (디렉터리 관련)

#!/bin/bash
echo "----- Directoiry Lists -----"
echo -n "Input Dir Path: "
read path
for lst in $(ls $path) : 디렉터리 안에 내용을 저장해서 출력해줌
do
        echo $lst
done


* Test7

#!/bin/bash
sum=0
for (( i=1;i<=10;i++ )) : 1~10까지의 누적 합
do
        sum=`expr $sum + $i`
done
echo $sum



[while문]


* Test1

#!/bin/bash 
while [ -f /etc/passwd ] : /etc/passwd 파일이 있으면 참
do
        tail -5 /etc/passwd
        break  : 이게 없으면 계속 실행되니 주의
done


* Test2

#!/bin/bash
echo -n "Your Password Input: " : 패스워드가 1234가 아니면 반복되는 구조
read pass
while [ $pass != "1234" ]
do
        echo "Plz Enter Again"
        echo -n "Your Password Input: "
        read pass
done
echo "Login Success"


* Test3
- VMware에서 firefox 켜놓고 실행

#!/bin/bash
echo "===== Process Check! ====="
echo -n "Input Apps Name: "
while read apps
do
        if pidof $apps; then
                echo -n "Running PID $apps: " 
                pidof $apps; : pidof는 프로세스 아이디 값, 값이 있으면 참
        else
                echo "Not Running $apps"
        fi
        echo -n "Exit(0), Continue(1): "
        read choice
        if [ $choice == 1 ]; then
                echo -n "Again Input Apps Name: "
        else
                echo "Scripts Finished"
                exit 0
        fi
done

- 결과
# ./while_test3.sh
===== Process Check! =====
Input Apps Name: firefox
55781 55656 55591 55573 55341
Running PID firefox: 55781 55656 55591 55573 55341
Exit(0), Continue(1): 0
Scripts Finished



[함수] : 조별과제시 함수 구조 형식으로 만들어야 한다.

* Test1

#!/bin/bash
function Sum() {
        echo "Sum: `expr $num1 + $num2`"
}
echo -n "Enter First Number: "
read num1
echo -n "Enter Second Number: "
read num2
Sum  : 함수 호출


* Test2 (인자 값을 넣어 호출)

#!/bin/bash
function Result() {
        if [ $1 -eq "1" ]; then
                echo Check[ OK ]
        else
                echo Check[ NO ]
        fi
}
echo -n "Input Data 1 or 0: "
read num
Result $num : Result는 $0 이 되는 거고 $num은 $1이 되는 거다.



* Test3

#!/bin/bash
func1() {
        echo "Func1 is Return Func"
        return 100
}
func1
return_val=$? : 이건 대기하고 있다고 생각
echo "Func1 Return Value: $return_val"



[eval] : 자주 사용하는 명령어를 변수에 저장해서 불러오는 형식, 일회성일 경우에는 $(명령어)가 편함

#!/bin/bash
str1="uname -sr" : 리눅스 시스템 정보 확인 명령어
echo -n "Linux System Info: "
eval $str1 : 여기에 eval을 쓰면 명령어를 실행해달라는 뜻 echo $str1을 쓰면 uname -sr 문자열 형식으로 나옴
echo ""
echo ""

cmd_lst="ls /usr/bin | wc -l" : 실행파일 행의 개수 출력 명령어
echo -n "Linux Command Count: "
eval $cmd_lst
echo ""
echo ""

if [ $1 ]; then : 파라미터값 입력 시에만 명령어 실행됨
        proc_info="ps -ef | grep $1"
        eval $proc_info
else
        proc_info="Not Found Aguments"
        echo $proc_info
fi



[$(명령어)]

#!/bin/bash
echo "[ Shadow File 3 Line Check ]"
echo "$(head -3 /etc/shadow)"
echo ""
echo ""
echo "Today is $(date)"



[set, unset] : 환경변수 생성,해제

* unset Test

# export MyVAR="Hello World" : 환경변수 설정(보통 export사용)
# echo $MyVAR
Hello World

# unset MyVAR : 환경변수 해제
# echo $MyVAR


* set Test (스크립트 생성시 도움되는)

- 스크립트는 멈추지 않고 전부 실행함, 그래서 에러가 발생할 시점에 set 설정을 하는 거!
- itbank 계정으로 접속

#!/bin/bash
echo "Before Error"
cd /root
echo "After Error"

- 결과
$ ./set_test.sh
Before Error
./set_test.sh: line 3: cd: /root: 허가 거부 : 일반 사용자는 root 못 감
After Error


#!/bin/bash
set -e echo "Before Error" : 에러가 발생할 지점에 set -e를 넣으면 에러 발생과 동시에 스크립트가 멈춘다 
cd /root
echo "After Error"