a=$(date)
echo $a
a=`date`
echo $a
expr 1 + 5
a=$[1 + 5]
$[1 + 5]를 하면 6이라는 결과가 command로 입력된다(6을 입력하는 것과 같은 결과). 따라서 계산 결과를 변수에 담아 활용해야 한다.
bc를 활용한 계산
b=$(echo "scale=2; 3.14 * 3.3" | bc)
echo $b
if [조건식] 또는 명령
then
else
fi
"a"="a"
-z "문자열 또는 변수"
수식1 -eq 수식2(또는 변수)
-d: 디렉토리면 참
-w: 파일인데 쓰기 가능
-x: 실행 가능
두 가지 이상의 조건을 모두 만족하거나 하나만 만족하면 참
[ 조건식 1 ] && [ 조건식 2 ]
[ 조건식 1 ] || [ 조건식 2 ]
[[ $USER == u* ]] || [[ $HOSTNAME == h* ]]
case $answer in
gildong)
echo "hi gildong";;
chulsoo)
echo "hi chulsoo";;
*)
echo "I don't know you";;
esac
예 1)
for 변수 in lists
do
echo "hello $변수"
done
예 2)
for test in A B C
do
echo "hello $test"
done
예 3)
for test in $(cat /etc/passwd | grep user1)
> do
> echo "hello $test"
> done
hello user1:x:1000:1000:user1:/home/user1:/bin/bash
예 4)
IFS=:
for test in $(cat /etc/passwd | grep user1)
> do
> echo "hello $test"
> done
hello user1
hello x
hello 1000
hello 1000
hello user1
hello /home/user1
hello /bin/bash
IFS=$' \t\n'
예 1)
for file in ~/.b*
> do
> echo $file
> done
/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc
예 2)
for file in ~/.b* /home/user1/test
> do
> echo $file
> done
/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc
/home/user1/test
실제로 /home/user1에 아무 파일이나 폴더가 없지만 결과에 나타나있다. 우리가 원하는 값이 아니므로 조건문을 통해 해당 파일이나 폴더의 유무를 체크하고 결과를 출력하는 것이 좋을 것이다.
for (( i=1; i<=3; i++ ))
> do
> echo $i
> done
1
2
3
vi db.txt
| name | age | addr
| gildong | 24 | 용인
| chulsoo | 25 | 서울
cat db.txt
cat db.txt | grep -v name
cat db.txt | grep -v name | grep gildong
cat db.txt | grep -v name | grep gildong | gawk '{print $2}'
cat db.txt | sed '/^$/d'
while은 조건이 참이라면 계속해서 반복해라. 참인 동안은 반복해라
while [1]
do
echo "hello"
done
우리는 메뉴 생성 시 종료 없이 계속해서 메뉴의 내용을 출력하고자 하는 경우 주로 사용한다.
#!/bin/bash
var1=3
while [ $var1 -gt 0 ]
do
echo "$var1"
var1=$[ $var1 - 1 ]
done
3
2
1
예) 인스턴스의 이름: test
인스턴스의 개수: 3
test-1, test-2, test-3 생성
for (( i=1; i<=$num; i++ ))
do
virt-install --name ${name}-${i}
done
echo "인스턴스 $i개가 정상적으로 생성되었습니다"
예) 로그인 프로그램
#!/bin/bash
read -s -p "비밀번호: " pass
echo
while [ $pass != "1234" ]
do
echo "잘못된 패스워드입니다."
read -s -p "비밀번호: " pass
echo
done
echo "로그인 성공"
-s: secure
-p: prompt
while과 반대로 동작한다.
while은 참일 때 동작해서, 거짓일 때 종료된다.
until은 거짓일 때 동작해서, 참일 때 종료된다.
#!/bin/bash
var1=100
until [ $var1 -eq 0 ]
do
echo $var1
var1=$[ $var1 - 25 ]
done
100
75
50
25
반복문의 한 종류로 주로 메뉴 생성에 사용된다
select 변수명 in 리스트
do
명령 or 변수
done
사용자로부터 값을 받기 위해서는 프롬프트가 필요하다.
ps1 -> 쉘에서 명령 입력 행 [root@localhost ~]#
ps2 -> 명령의 연결
ps3 -> 메뉴를 출력하고 메뉴에서 선택하도록 프롬프트를 띄운다
예 1)
#!/bin/bash
PS3="실행하고 싶은 명령을 선택하세요: "
select comm in 'ls -l' date pwd exit
do
$comm
done
1) ls -l
2) date
3) pwd
4) exit
실행하고 싶은 명령을 선택하세요: 1
total 20
-rwxr-xr-x 1 root root 1139 Jul 27 09:11 cvm.sh
-rw-r--r-- 1 root root 72 Jul 27 10:13 db.txt
-rwxr-xr-x 1 root root 197 Jul 27 10:49 test1.sh
-rwxr-xr-x 1 root root 89 Jul 27 10:53 test2.sh
-rwxr-xr-x 1 root root 125 Jul 27 11:15 test3.sh
실행하고 싶은 명령을 선택하세요: 2
Wed Jul 27 11:16:10 KST 2022
실행하고 싶은 명령을 선택하세요: 3
/root/0727
실행하고 싶은 명령을 선택하세요: 4
select를 단독으로 사용하면 명령을 그대로 나열해야 하므로 case와 함께 사용하면 효율적이다.
예 2) case와 함께 사용하기
#!/bin/bash
PS3="실행하고 싶은 명령을 선택하세요: "
select comm in "디렉토리파일확인" "날짜확인" "위치확인" "종료"
do
case $comm in
디렉토리파일확인)
ls -l ;;
날짜확인)
date ;;
위치확인)
pwd ;;
종료)
exit ;;
*)
echo "잘못된 번호를 선택했습니다";;
esac
done
1) 디렉토리파일확인 3) 위치확인
2) 날짜확인 4) 종료
실행하고 싶은 명령을 선택하세요: 1
total 24
-rwxr-xr-x 1 root root 1139 Jul 27 09:11 cvm.sh
-rw-r--r-- 1 root root 72 Jul 27 10:13 db.txt
-rwxr-xr-x 1 root root 197 Jul 27 10:49 test1.sh
-rwxr-xr-x 1 root root 89 Jul 27 10:53 test2.sh
-rwxr-xr-x 1 root root 125 Jul 27 11:15 test3.sh
-rwxr-xr-x 1 root root 349 Jul 27 11:22 test4.sh
실행하고 싶은 명령을 선택하세요: 2
Wed Jul 27 11:23:35 KST 2022
실행하고 싶은 명령을 선택하세요: 3
/root/0727
실행하고 싶은 명령을 선택하세요: 0
잘못된 번호를 선택했습니다
실행하고 싶은 명령을 선택하세요: 4
quiz. 원격지와의 통신 상태를 확인하기 위해 우리는 ping을 사용할 예정이다.
www.google.com, www.naver.com, www.daum.net으로 ping을 보내기 위한 프로그램을 select와 case를 이용하여 구현해보세요!
#!/bin/bash
PS3="실행하고 싶은 명령을 선택하세요: "
select comm in "구글" "네이버" "다음"
do
case $comm in
"구글")
ping www.google.com -c 1 ;;
"네이버")
ping www.naver.com -c 1 ;;
"다음")
ping www.daum.net -c 1 ;;
*)
exit ;;
esac
done
#!/bin/bash
for (( a=1; a < 4; a++ ))
do
echo "OUTER : $a"
for (( b=1; b < 100; b++ ))
do
if [ $b -eq 5 ]
then
break
fi
echo " INNER : $b"
done
done
OUTER : 1
INNER : 1
INNER : 2
INNER : 3
INNER : 4
OUTER : 2
INNER : 1
INNER : 2
INNER : 3
INNER : 4
OUTER : 3
INNER : 1
INNER : 2
INNER : 3
INNER : 4
inner loop가 종료된다.
#!/bin/bash
for (( a=1; a < 4; a++ ))
do
echo "OUTER : $a"
for (( b=1; b < 100; b++ ))
do
if [ $b -gt 4 ]
then
break 2
fi
echo " INNER : $b"
done
done
OUTER : 1
INNER : 1
INNER : 2
INNER : 3
INNER : 4
outer loop가 종료된다.
#!/bin/bash
for (( i=1; i < 15; i++ ))
do
if [ $i -gt 5 ] && [ $i -lt 10 ]
then
continue
fi
echo "num: $i"
done
num: 1
num: 2
num: 3
num: 4
num: 5
num: 10
num: 11
num: 12
num: 13
num: 14
$*: 모든 매개 변수를 하나로 다룸
$@: 각각의 매개 변수를 분리해서 다룸
$PATH -> 실행파일의 위치를 지정하는 위치변수
$? -> 직전 실행 명령이 오류인지 참인지를 판별하는 종료 코드
(0이면 True, 나머지는 모두 False)
hello hi nice to meet you
gawk '{print $1}'
-> hello
[명령어] a b c
$1: a
$*: a b c 전체를 하나의 데이터로 취급
$@: a b c 각각의 데이터를 묶어서 처리
$#: 매개변수의 개수 -> 3
$0: 제일 앞 명령어
echo -n "name: "
read name
read -p "name: " last first
-p: prompt
echo $last
이
echo $first
건우
read -t 3 -p "name: " name
-t 3: 3초 내로 입력되지 않으면 종료됨
입력되는 글자수가 채워지면 종료
read -n1 -p "yes or no: " ans
-n1: 한 글자가 채워지면 종료
read -s -p "yes or no: " ans
-s: secure
입력할 떄 값이 보이지 않는다
mkdir 0727 && cd 0727
touch cvm.sh && chmod +x cvm.sh && vi cvm.sh
#!/bin/bash
clear
echo -e "\t\t\t인스턴스 생성 프로그램 "
echo
echo "설치할 이미지를 선택하세요"
echo "1. CentOS 7"
echo "2. Ubuntu 18.04"
echo
echo -n "이미지 선택 : "
read name
if [ -z $name ]
then
echo "이미지를 선택하지 않았습니다. 프로그램이 종료됩니다"
exit
elif [ $name -eq 1 ]
then
name="CentOS7-Base.qcow2"
elif [ $name -eq 2 ]
then
name="Ubuntu1804.qcow2"
else
echo "잘못된 번호를 선택했습니다. 프로그램이 종료됩니다"
exit
fi
echo
echo -n "인스턴스 이름 입력 : "
read instancename
cp /cloud/$name /cloud/${instancename}.qcow2
echo
echo -n "CPU 개수 선택(1~4) : "
read vcpus
echo
echo -n "메모리 사이즈 선택(1~4GB) : "
read tempmem
ram=$(expr $tempmem \* 1024 )
echo
echo "설치가 진행됩니다"
# 프로그램 설치 시작
virt-install --name $instancename --vcpus $vcpus --ram $ram --network network:default,model=virtio --disk /cloud/${instancename}.qcow2 --import --noautoconsole > /dev/null
#확인
virsh list --all
인스턴스 2개 생성 -> test1, test2
touch allvm && chmod +x allvm && mv allvm /usr/bin
#!/bin/bash
for vm in $(virsh list --all | grep -v Id | gawk '{print $2}' | sed '/^$/d' )
do
virsh $1 $vm
done
case $1 in
start)
echo "모든 인스턴스가 실행되었습니다";;
destroy)
echo "모든 인스턴스가 종료되었습니다";;
undefine)
echo "모든 인스턴스가 삭제되었습니다";;
*)
echo "알수없는 명령어";;
esac
virsh list --all
virsh list --all | grep -v Id
virsh list --all | grep -v Id | gawk '{print $2}'
virsh list --all | grep -v Id | gawk '{print $2}' | sed '/^$/d'
[확인하고 싶은 것]
1. 가상 머신의 ip 주소
virsh domifaddr test1
virsh domifaddr test1 | grep -v Name
virsh domifaddr test1 | grep -v Name | gawk '{print $4}'
virsh domifaddr test1 | grep -v Name | gawk '{print $4}' | sed '/^$/d'
virsh domifaddr test1 | grep -v Name | gawk '{print $4}' | sed '/^$/d' | gawk -F/ '{print $1}'
yum -y install sysstat
sar 1 3
1초마다 cpu를 3번 점검하고 평균값을 보여줌
Linux 3.10.0-1160.71.1.el7.x86_64 (gunwoo) 07/27/2022 _x86_64_ (4 CPU)
01:58:43 PM CPU %user %nice %system %iowait %steal %idle
01:58:44 PM all 0.25 0.00 0.25 0.00 0.00 99.49
01:58:45 PM all 2.30 0.00 4.59 0.00 0.00 93.11
01:58:46 PM all 0.76 0.00 0.51 0.00 0.00 98.73
Average: all 1.10 0.00 1.78 0.00 0.00 97.12
가상머신들의 cpu 상태를 강제로 100%로 만들기 위한 구성 내용
virsh console test1
Connected to domain test1
Escape character is ^]
CentOS Linux 7 (Core)
Kernel 3.10.0-1127.el7.x86_64 on an x86_64
localhost login: root
Password:
[root@localhost ~]#
yum -y install epel-release
yum -y install stress
stress -c 1
ctrl + ]를 눌러서 test1에서 빠져나오기
[host]
sar 1 3
Linux 3.10.0-1160.71.1.el7.x86_64 (gunwoo) 07/27/2022 _x86_64_ (4 CPU)
02:04:43 PM CPU %user %nice %system %iowait %steal %idle
02:04:44 PM all 25.13 0.00 0.25 0.00 0.00 74.62
02:04:45 PM all 25.13 0.00 0.00 0.00 0.00 74.87
02:04:46 PM all 25.25 0.00 0.00 0.00 0.00 74.75
Average: all 25.17 0.00 0.08 0.00 0.00 74.75
test1 접속하기
virsh console test1
yum -y install virt-top
virt-top
ID S RDRQ WRRQ RXBY TXBY %CPU %MEM TIME NAME
7 R 0 0 104 0 25.2 13.0 4:59.30 test1
undefine은 인스턴스를 삭제하는 명령이다. 단, 인스턴스가 삭제되고 디스크는 여전히 /cloud 상에 남아있게 된다. undefine했을 때 함께 다음의 옵션을 추가하여 디스크까지 삭제되도록 해보세요!
"--remove-all-storage"
allvm undefine -> virsh undefine test1 --remove-all-storage
#!/bin/bash
for vm in $(virsh list --all | grep -v Id | gawk '{print $2}' | sed '/^$/d' )
do
if [ $1 = "undefine" ]
then
virsh $1 $vm --remove-all-storage
else
virsh $1 $vm
fi
done
case $1 in
start)
echo "모든 인스턴스가 실행되었습니다";;
destroy)
echo "모든 인스턴스가 종료되었습니다";;
undefine)
echo "모든 인스턴스와 스토리지가 삭제되었습니다";;
*)
echo "알수없는 명령어";;
esac
~
다음의 조건을 만족하는 스크립트를 작성하세요
1. 다음의 조건을 만족하는 스크립트를 작성하세요
인스턴스 생성 프로그램
- 설치할 이미지를 선택하세요
1. centos7
2. ubuntu 18.04
선택: 1
- 설치할 인스턴스의 이름을 입력하세요: test
- 설치할 인스턴스의 개수 선택[1~4]: 3
- cpu 개수 선택[1~4]: 1
- 메모리 사이트 선택[1~4G]: 1
설치를 진행하겠습니다.
[결과 안내]
test1의 ip 주소: 192.168.122.201
test2의 ip 주소: 192.168.122.202
현재 호스트의 cpu 사용률: 23.03%
설치가 완료되었습니다. 계속 진행하시려면 아무 키나 입력허세요. (키를 입력하면 프로그램 처음부터 실행)
조건: 잘못된, null 값이 입력되면 화면에는 '잘못된 입력입니다. 다시 입력하세요'가 나오도록
#!/bin/bash
clear
echo -e "\t\t\t인스턴스 생성 프로그램 "
echo
echo "설치할 이미지를 선택하세요"
echo "1. CentOS 7"
echo "2. Ubuntu 18.04"
echo
echo -n "이미지 선택 : "
read name
if [ -z $name ]
then
echo "이미지를 선택하지 않았습니다. 프로그램이 종료됩니다"
exit
elif [ $name -eq 1 ]
then
name="CentOS7-Base.qcow2"
elif [ $name -eq 2 ]
then
name="Ubuntu1804.qcow2"
else
echo "잘못된 번호를 선택했습니다. 프로그램이 종료됩니다"
exit
fi
echo -n "인스턴스 이름 입력 : "
read instancename
if [ -z $instancename ]
then
echo "인스턴스 이름이 입력되지 않았습니다. 프로그램이 종료됩니다."
exit
fi
echo
echo -n "설치할 인스턴스의 개수 선택(1~4): "
read instancenum
if [ -z $instancenum ]
then
echo "인스턴스 개수가 입력되지 않았습니다. 프로그램이 종료됩니다."
exit
fi
echo
echo -n "CPU 개수 선택(1~4) : "
read vcpus
if [ -z $vcpus ]
then
echo "CPU 개수가 입력되지 않았습니다. 프로그램이 종료됩니다."
exit
fi
echo
echo -n "메모리 사이즈 선택(1~4GB) : "
read tempmem
if [ -z $tempmem ]
then
echo "메모리 사이즈가 입력되지 않았습니다. 프로그램이 종료됩니다."
exit
fi
ram=$(expr $tempmem \* 1024 )
echo
echo "설치가 진행됩니다"
for (( i=1; i<=instancenum; i++ ))
do
cp /cloud/$name /cloud/${instancename}-${i}.qcow2
# 프로그램 설치 시작
virt-install --name ${instancename}-${i} --vcpus $vcpus --ram $ram --network network:default,model=virtio --disk /cloud/${instancename}-${i}.qcow2 --import --noautoconsole > /dev/null
done
#확인
virsh list --all
# cpu 사용률
echo -n "현재 호스트의 cpu 사용률(%): "
echo -n sar 1 3 | tail -1 | gawk '{print 100-$8}'
echo "retreiveing ip address. please wait for $instancenum minutes"
sleeptime=$[ $instancenum * 60 ]
sleep $sleeptime
for (( i=1; i<=instancenum; i++ ))
do
echo -n "${instancename}-${i}의 주소: "
virsh domifaddr ${instancename}-${i} | grep -v Id | gawk '{print $4}' | sed '/^$/d' | gawk -F/
'{print $1}'
done
-F -> IFS
-f -> file
grep: 행 추출(줄 단위)
gawk: 열 추출
[root@gunwoo 0727]# gawk '{print "안녕하세요"}'
a
안녕하세요
b
안녕하세요
c
안녕하세요
-> 값을 입력하면 print됨
[root@gunwoo 0727]# gawk 'BEGIN {print "HELLO"}'
HELLO
-> BEGIN: 뒤에 값을 입력하지 않아도 출력됨
[root@gunwoo 0727]# cat db.txt
| name | age | addr
| gildong | 24 | 용인
| chulsoo | 25 | 서울
[root@gunwoo 0727]# gawk '{print $2}' db.txt
name
gildong
chulsoo
-> {print 2}는 두 번째 column 출력
[root@gunwoo 0727]# gawk '{print $0}' db.txt
| name | age | addr
| gildong | 24 | 용인
| chulsoo | 25 | 서울
-> {print $0}는 전체 출력
[root@gunwoo 0727]# gawk -F: '{print $1}' /etc/passwd | head -5
root
bin
daemon
adm
lp
-> 사용자 정보 출력
[root@gunwoo 0727]# gawk -F: 'BEGIN {print "보고"} {print $1}' /etc/passwd | head -5
보고
root
bin
daemon
adm
-> BEGIN {print "문자열"}을 하면 맨 앞에 문자열 출력
[root@gunwoo 0727]# gawk -F: '{print $1} END {print "보고 완료"}' /etc/passwd | tail -5
nfsnobody
apache
nginx
mysql
보고 완료
-> END {print "문자열"}을 하면 맨 끝에 문자열 출력
[root@gunwoo 0727]# echo "this is a test" | gawk '/test/{print $0}'
this is a test
-> /test/{print $0}: test와 동일한 문자열이 있다면 전체 내용($0)을 출력하라.
-> "this is a test"에 "test"가 있으므로 전체 내용을 출력한다.
[root@gunwoo 0727]# echo "bt" | gawk '/be?t/{print $0}'
bt
bt 또는 bet일 때 값을 출력
*: 바로 앞 문자열을 0번 이상 사용할 수 있다
?: 바로 앞 문자를 0번 또는 1번 사용할 수 있다.
[root@gunwoo 0727]# echo "bet" | gawk '/b[ae]?t/{print $0}'
bet
-> bt 또는 bat 또는 bet 또는 baet리면 값을 출력
[root@gunwoo 0727]# echo "bet" | gawk '/b[a-z]?t/{print $0}'
bet
-> a부터 z
[root@gunwoo 0727]# echo "bt" | gawk '/be+t/{print $0}'
[root@gunwoo 0727]# echo "bet" | gawk '/be+t/{print $0}'
bet
+: 한 개 이상 반드시 있어야한다.
[root@gunwoo 0727]# echo "beet" | gawk '/be{1}t/{print $0}'
[root@gunwoo 0727]# echo "beet" | gawk '/be{1,2}t/{print $0}'
beet
[root@gunwoo 0727]# echo "beet" | gawk '/be[a-z]{1,3}t/{print $0}'
beet
{} -> 안에 있는 숫자 만큼 있어야 한다.
[root@gunwoo 0727]# echo "the cat is asleep" | gawk '/cat|dog/{print $0}'
the cat is asleep
[root@gunwoo 0727]# echo "the cat is asleep" | gawk '/[ch]at|dog/{print $0}'
the cat is asleep
[root@gunwoo 0727]# echo "the hat is asleep" | gawk '/[ch]at|dog/{print $0}'
the hat is asleep
[root@gunwoo 0727]# echo "the dog is asleep" | gawk '/[ch]at|dog/{print $0}'
the dog is asleep
[root@gunwoo 0727]#
[root@gunwoo 0727]# echo "Sat" | gawk '/Sat(urday)?/{print $0}'
Sat
[root@gunwoo 0727]# echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
Saturday
[root@gunwoo 0727]# echo "Satur" | gawk '/Sat(urday)?/{print $0}'
Satur
[root@gunwoo 0727]#
기존 작성되어 있는 코드에서
인스턴스 이름 -> 반드시 소문자만 이용(5~10 글자)
CPU -> 반드시 숫자(1~4)
RAM -> 반드시 숫자(1~4)
vi /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
위의 코드 추가하기
yum clean all
yum -y install MariaDB
vi /etc/my.cnf.d/server.cnf 파일에서
[mysqld] 섹션에 아래와 같은 내용을추가해 둔다.
vi /etc/my.cnf.d/server.cnf
[mysqld]
init_connect="SET collation_connection=utf8_general_ci"
init_connect="SET NAMES utf8"
character-set-server=utf8
collation-server=utf8_general_ci
systemctl start mariadb
mysql -u root -p
[그냥 엔터]
mariadb> status