변수: 임시로 값을 저장하여 활용할 수 있는 박스
array[1] = "gildong"
위처럼 쓰면 무엇을 의미하는지 알기 어렵다
array["name"] = "gildong"
-> key: value -> 연관배열(딕셔너리)
배열은 번호를 이용하고 연관 배열은 키:value 를 이용한다.
자료 검색, 관리 등에 유용하다. 또한 연관 배열은 json 형태와 유사하게 키:value 를 사용하므로 다른 프로그래밍 언어들과 연계해서 사용하기가 유용하다.
-> NoSQL에 자료 관리가 유용하다.
bash에서도 동일하게 변수, 배열, 연관 배열의 사용이 가능하다.
http://bahndal.egloos.com/608900
변수
set | grep IFS
-> IFS=$' \t\n'
IFS는 사용자가 쉘 사용 시 각각의 데이터를 구분하는 구분자
공백, \t, \n
ex) a.txt b.txt c.txt라고 입력을 하면 세 파일이 다른 데이터라는 것을 구분함
[root@gunwoo ~]# cat /etc/passwd | grep user1
user1:x:1000:1000:user1:/home/user1:/bin/bash
위에서 만약 IFS를 콜론(:)으로 설정한다면 데이터를 구분할 수 있음
bash에서는 변수를 미리 지정할 필요 없고, 데이터타입을 지정할 필요도 없다.
변수 선언과 동시에 값을 지정한다. bash는 모든 변수값이 str이다.
name=hello (o)
name = hello (x) -> name에 =와 hello라는 옵션을 적용한 것으로 취급
name="hello all" (o)
#!/bin/bash
echo "사용자 이름": $USER
echo "홈 디렉토리": $HOME
exit 0
exit 0: 종료 코드를 강제로 "0"으로 설정하겠다.
ping www.google.com -c 3
echo $?
-> 0
echo $?: 직전 실행한 코드, 명령의 종료 상태를 반환
0은 정상 종료를 의미함
pin www.google.com -c 3
echo $?
ping www.test.pri -c 3
echo $?
touch test1.sh
cat << EOF > test1.sh
> #!/bin/bash
>
> echo "hello all"
> EOF
ps1(Default interaction prompt): # 일반 프롬프트
ps2(Continuation interactive prompt): > (명령의 연결)
ps3(Prompt used by “select” inside shell script): select와 연계해서 사용
https://www.thegeekstuff.com/2008/09/bash-shell-take-control-of-ps1-ps2-ps3-ps4-and-prompt_command/
방법 1)
/bin/bash test1.sh
방법 2)
bash test1.sh
bash 경로를 다 입력하지 않아도 되는 이유? -> $PATH에 경로가 정의되어있기 떄문
방법 3)
sh test1.sh
sh -> /bin/bash에 링크 걸려있음 -> bash를 실행하는 것과 동일하다.
방법 4)
chmod u+x test1.sh
./test1.sh
명령의 결과를 변수나 파일에 담아 활용하기
방법 1
test1=`date`
echo $test1
방법 2
test2=$(date)
echo $test2
mktemp /tmp/hello.XXXXXX
test1=$(mktemp /tmp/hello.XXXXXX)
echo $test1
test1=$(mktemp /tmp/hello.XXX)
echo $test1
expr 10 + 2
expr 10 - 2
expr 10 / 2
expr 10 % 2
expr 10 * 2
'*'를 패턴과 혼동할 수 있으므로 계산이 되지 않는다. *는 any를 뜻함
expr 10 \* 2
res1=`expr 10 + 2`
echo $res1
res1=$(expr 10 + 2)
echo $res1
변수명=$[계산식]
res3=$[10 + 2]
echo $res3
계산 결과를 화면에 출력하고 싶다면
`계산식`
하지만 $[계산식]을 쓰면 출력이 아니라 결과값을 명령으로 실행하게 되므로 대괄호의 계산식은 반드시 변수와 함께 사용해야 한다.
`expr 1.1 + 2.2`
bc
quit
bc -q
-q: quiet. don't print initial banner
5/4
scale=2
5/4
scale=5
5/4
var1=10
var1 * 4
print var1
지역 변수는 이 프로그램 안에서만 사용 가능. 프로그램 밖에서는 쓸 수 없다.
변수명=$(echo "옵션; 계산식" | bc)
var1=$(echo "scale=4; 3.14 * 3" | bc); echo $var1
파라미터 변수(위치 변수), 매개변수(함수 내로 전달하는 변수)로도 활용 가능
dnf -y install httpd
$0 -> dnf
$1 -> -y
$2 -> install
$3 -> httpd
파라미터 변수는 명령과 옵션 등을 변수로 활용할 수 있다.
ex)
test2.sh gildong 24 용인
test2.sh chulsoo 25 서울
$1은 DB 저장할 때 테이블의 첫 번째 열에 저장해라
$2는 DB 저장할 때 테이블의 두 번째 열에 저장해라
$name=$1
$age=$2
$addr=$3
전체는 $*, $@이다.
vi test2.sh
#!/bin/bash
echo "hello $1"
./test2.sh 철수
./test2.sh gildong
if 명령 또는 [조건] -> ["woo" = "woo"]
then
참일 경우
else
거짓일 경우
fi
조건 대신 명령이 들어가면 명령이 정상적으로 실행되었을 때가 참이 된다.
#!/bin/bash
if pwd
then
echo "finished"
fi
#!/bin/bash
if pwd > /dev/null
then
echo "finished"
fi
#!/bin/bash
echo -n "username: "
read testuser
if grep $testuser /etc/passwd
then
cat /etc/passwd | grep $testuser
else
echo "no user, $testuser"
fi
사용자로부터 httpd가 설치되어있는지 여부를 확인하고 설치되어있지 않다면 해당 패키지를 설치하도록 한다. 만약 설치되어있다면 버전을 출력하고 그렇지 않다면 설치하는 프로그램을 작성하라.
#!/bin/bash
echo -n "package name: "
read package
if rpm -qa | grep $package > /dev/null
then
$package -v
else
yum -y install $package
fi
검색하고 싶은 패키지?: httpd
설치되어있음.
httpd 버전 출력
검색하고 싶은 패키지?: haproxy
설치되어있지 않다.
설치가 진행됨
#!/bin/bash
testuser=user11
if grep $testuser /etc/passwd
then
echo "ok"
else
echo "no user"
if ls -d /home/$testuser # -d: 디렉토리
then
echo "dir is there!"
fi
fi
user11이 없을 때
user11이 있을 때
원격지에 접속한 특정 사용자의 ssh 연결을 종료시켜라
접속을 종료시키고 싶은 ip를 입력하세요: 192.168.1.99
해당 ip는 없습니다.
또는
연결을 종료시켰습니다.
who
-> 접속된 사용자 확인
ps -ef | grep sshd
ps -ef | grep sshd | grep pts/0
ps -ef | grep sshd | grep pts/0 | head -1
ps -ef | grep sshd | grep pts/0 | head -1 | gawk '{print $2}'
kill -9 1490
#!/bin/bash
echo -n "차단할 IP 주소 입력 : "
read ipaddr
if who | grep $ipaddr
then
pts=$(who | grep $ipaddr | gawk '{print $2}' | head -1)
pid=$(ps -ef | grep sshd | grep $pts | gawk '{print $2}')
kill -9 $pid
else
echo "해당 사용자는 접속하지 않았음"
fi
#!/bin/bash
echo -n "차단할 IP 주소 입력 : "
read ipaddr
if who | grep $ipaddr
then
pts=$(who | grep $ipaddr | gawk '{print $2}' | head -1)
pid=$(ps -ef | grep sshd | grep $pts | gawk '{print $2}')
echo "${ipaddr}은 차단될 예정입니다"
sleep 2
# 연결 종료된 ip를 영구적으로 차단하기
route add -host $ipaddr reject
kill -9 $pid
else
echo "해당 사용자는 접속하지 않았음"
fi
ssh 원격 연결이 차단되었으므로 VM에서 조작하기
yum -y install net-tools
route
route delete -host 192.168.1.31 reject
route
차단이 해제되었음
#!/bin/bash
echo -n "your name?: "
read username
if [ $username = "root" ]
then
echo "당신은 루트군요"
else
echo "당신은 일반 사용자입니다"
fi
-n: 내용이 있으면 참
-z: 비어있으면 참
-n은 간혹 오류가 발생하니 -z를 사용하자.
[ ] && [ ] -> 두 조건을 모두 만족하면 참
[ ] || [ ] -> 두 조건 중 하나라도 만족하면 참
문자열 비교에 대한 고급 기능을 제공한다. 괄호 안에서 패턴(*) 사용이 가능하다.
bash에서는 잘 동작하지만 모든 쉘이 지원하는 것은 아니다.
[[ == ]]
"=="는 오른쪽에서 패턴을 사용할 수 있다.
if [[ $USER == r* ]]
then
echo "Hello $USER"
fi
실습
사용자로부터 값을 입력 받아 가성머신 생성하기
yum -y install qemu-kvm virt-install libvirt virt-manager libguestfs-tools
yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install https://github.com/kimchi-project/kimchi/releases/download/2.5.0/wok-2.5.0-0.el7.centos.noarch.rpm
yum -y install https://github.com/kimchi-project/kimchi/releases/download/2.5.0/kimchi-2.5.0-0.el7.centos.noarch.rpm
위에서 yum install이 안 된다면 wget으로 가져와서 받기
cd /tmp
wget https://github.com/kimchi-project/kimchi/releases/download/2.5.0/wok-2.5.0-0.el7.centos.noarch.rpm
wget https://github.com/kimchi-project/kimchi/releases/download/2.5.0/kimchi-2.5.0-0.el7.centos.noarch.rpm
yum install -y wok-2.5.0-0.el7.centos.noarch.rpm
yum install -y kimchi-2.5.0-0.el7.centos.noarch.rpm
https://mangolassi.it/topic/15882/kimchi-kvm-updated-and-better-and-easy-guide-for-kvm-beginners
systemctl enable wokd
systemctl restart wokd
이후 https://서버IP:8001 로 접속
vi /etc/libvirt/qemu.conf
442째 줄 user="root" -> 해시 제거
446째 줄 group = "root" -> 해시 제거
systemctl daemon-reload
systemctl restart wokd
systemctl restart libvirtd
systemctl enable libvirtd
cd /cloud
wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-2003.qcow2.xz
xz -d CentOS-7-x86_64-GenericCloud-2003.qcow2.xz
mv CentOS-7-x86_64-GenericCloud-2003.qcow2 CentOS7-Base.qcow2
virt-customize -a CentOS7-Base.qcow2 --root-password password:test123
KVM 인스턴스 생성하기
참고: https://velog.io/@ptah0414/DB-22-07-15-TIL#%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%84%A4%EC%B9%98
cp CentOS7-Base.qcow2 gildong.qcow2
virt-install --name gildong --vcpus 1 --ram 1024 --network network:default,model=virtio --disk gildong.qcow2 --import --noautoconsole
https://192.168.1.116:8001/#plugins/kimchi/tabs/guests 에서 인스턴스 생성 확인
조치 -> view serial -> ping, ifconfig 확인하기
cp CentOS7-Base.qcow2 chulsoo.qcow2
virt-install
--name chulsoo
--vcpus 1
--ram 1024
--network network:default,model=virtio
--disk chulsoo.qcow2
--import
--noautoconsole > /dev/null
https://192.168.1.116:8001/#plugins/kimchi/tabs/guests 에서 인스턴스 생성 확인
인스턴스 간 통신 확인
처음 프로그램이 샐행되면 화먄을 clear함
0. os 선택(1. CentOS7, 2. Ubuntu18.04, ..): 실습 시에는 1만 선택하기
1. 가상머신의 이름을 입력하세요: gildong (CentOS7-Base.qcow2 -> 복사 -> gildong.qcow2)
만약 인스턴스의 이름을 입력하지 않는다면, 화면에는 "이름이 입력되지 않았습니다. 종료됩니다"가 출력되고 종료된다. 이미지 복사 작업이 이루어지지 않는다.
2. cpu 개수 선택: 1~4 (실습 시에는 1만 선택하기 )
3. ram 사이지 선택: 1~4(실습 시에는 1만 선택하기) -> 1 81024 -> 1024
4. "설치가 진행됩니다." 출력하고 종료되도록 (virsh list --all) -> 설치된 모든 인스턴스 확인
#!/bin/bash
os=''
name=''
vpuc=''
ram=''
clear
echo -e "INSTANCE CREATION PROGRAM"
echo
echo "os를 선택하세요(1. CentOS7, 2. Ubuntu18.04)"
read os
if [ -z $os ]
then
echo "os가 선택되지 않았습니다. 종료됩니다."
exit 0
fi
echo -en "INSTANCE NAME: "
read name
if [ -z $name ]
then
echo "이름이 입력되지 않았습니다. 종료됩니다."
exit 0
fi
echo -en "HOW MANY CPUs DO YOU WANT: "
read vcpu
echo -en "MEMORY SIZE: "
read ram
ram=$[ $ram * 1024 ]
echo "설치가 진행됩니다."
cp CentOS7-Base.qcow2 ${name}.qcow2
virt-install --name $name --vcpus $vcpu --ram $ram --network network:default,model=virtio --disk $name.qcow2 --import --noautoconsole > /dev/null
virsh list --all
virsh list --all
virsh edit gildong
/gildong.qcow2
virsh domifaddr gildong
virsh destroy gildong
virsh undefine gildong --remove-all-storage
기본 형태
for 변수 in 리스트
do
commands
done
set | grep IFS
cat /etc/passwd | grep user1
IFS=:
for list in $(cat /etc/passwd | grep user1)
> do echo "LiST:$list" ; done
LiST:user1
LiST:x
LiST:1000
LiST:1000
LiST:user1
LiST:/home/user1
LiST:/bin/bash
IFS=$' \t\n'
cat /etc/passwd | grep user1
-> user1:x:1000:1000:user1:/home/user1:/bin/bash
cat /etc/passwd | grep user1 | gawk -F: '{print $6}'
-> /home/user1
"-F:": 임시로 IFS 변경하기 -> 콜론(:)을 기준으로 구분을 할 것임
-> 슬라이싱하여 여섯번째 문자열을 가져왔음
virsh list -all
virsh list --all | grep -v Id
-v: 특정 문자열을 포함한 열 지우기
virsh list --all | grep -v Id | gawk '{print $2}'
-> 두 번째 행만 보기
file 이름 -> allvm을 만들고
allvm start -> 모든 인스턴스가 실행
allvm destroy -> 모든 인스턴스가 종료됨
allvm undefine -> 모든 인스턴스가 삭제됨 (단, 디스크는 남아있도록)
touch allvm && chmod +x allvm && mv allvm /usr/bin && vi allvm
#!/bin/bash
for vm in $(virsh list --all | grep -v ID | gawk '{print $2}')
do
virsh $1 $vm
done
case $1 in
start)
echo "모든 인스턴스가 실행되었습니다";;
destroy)
echo "모든 인스턴스가 종료되었습니다";;
undefine)
echo "모든 인스턴스가 삭제되었습니다";;
*)
echo "알수없는 명령어";;
esac