[Linux] Arithmetic, KVM(Wok, Kimchi), IFS

gununoo·2022년 7월 26일
3

Linux

목록 보기
7/10
post-thumbnail

변수: 임시로 값을 저장하여 활용할 수 있는 박스

array[1] = "gildong"

위처럼 쓰면 무엇을 의미하는지 알기 어렵다

array["name"] = "gildong"

-> key: value -> 연관배열(딕셔너리)

배열은 번호를 이용하고 연관 배열은 키:value 를 이용한다.
자료 검색, 관리 등에 유용하다. 또한 연관 배열은 json 형태와 유사하게 키:value 를 사용하므로 다른 프로그래밍 언어들과 연계해서 사용하기가 유용하다.
-> NoSQL에 자료 관리가 유용하다.

bash에서도 동일하게 변수, 배열, 연관 배열의 사용이 가능하다.
http://bahndal.egloos.com/608900

변수

  • 환경 변수: 사용자가 리눅스 시스템에 로그인을 하게 되면 해당 환경 내에서 자동으로 부여되는 변수. 시스템 전체에 영향을 미친다. env, printenv, set
  • 사용자 변수: 사용자가 직접 만들어서 사용하는 변수. 해당 파일에서만 영향을 미친다.

IFS(Internal Field Separator)

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에서는 변수를 미리 지정할 필요 없고, 데이터타입을 지정할 필요도 없다.
변수 선언과 동시에 값을 지정한다. 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은 정상 종료를 의미함

비정상 종료

  • 127: command not found
pin www.google.com -c 3 
echo $?

  • 2
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/

bash로 쉘 스크립트 실행시키는 방법들

방법 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 
  • 보통 X를 세 자리에서 여섯 자리까지 사용함. 두 자리 이하는 생성되지 않음

계산하기

방법 1. expr

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 

방법 2. $[계산식]

변수명=$[계산식]
res3=$[10 + 2]
echo $res3

계산 결과를 화면에 출력하고 싶다면

`계산식`

하지만 $[계산식]을 쓰면 출력이 아니라 결과값을 명령으로 실행하게 되므로 대괄호의 계산식은 반드시 변수와 함께 사용해야 한다.

방법 3. bc(bash calculator)

`expr 1.1 + 2.2`
  • expr: non-integer argument -> 계산 불가
  • expr는 정수식만 계산 가능 -> bc를 이용해보자
bc 
quit 
  • bc 빠져나오기
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 

지역 변수는 이 프로그램 안에서만 사용 가능. 프로그램 밖에서는 쓸 수 없다.

bc를 이용한 계산 결과 활용하기

변수명=$(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문

if 명령 또는 [조건] -> ["woo" = "woo"]
then 
    참일 경우 
else 
    거짓일 경우 
fi 

조건 대신 명령이 들어가면 명령이 정상적으로 실행되었을 때가 참이 된다.

예시 1

#!/bin/bash

if pwd
then
        echo "finished"

fi
  • 조건문을 확인한 결과(pwd -> /root/0726)도 출력됨

예시 2

#!/bin/bash

if pwd > /dev/null
then
        echo "finished"

fi
  • pwd는 /dev/null로 보내버려서 출력을 하지 않음

예시 3

#!/bin/bash

echo -n "username: "
read testuser

if grep $testuser /etc/passwd 
then 
        cat /etc/passwd | grep $testuser 
else 
        echo "no user, $testuser"

fi 

quiz

사용자로부터 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
설치되어있지 않다.
설치가 진행됨

중첩 if문

#!/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 

-> 접속된 사용자 확인

  1. 현재 내 시스템에서 동작하는 프로세스 중 sshd 관련 프로세스를 출력하라
ps -ef | grep sshd 
  1. 1.의 결과 중 pts/0과 매치하는 행이 있다면 출력하라
ps -ef | grep sshd | grep pts/0 
  1. 앞선 결과는 실제 pts/0과 grep 명령어에서 pts/0을 사용하는 것 두 가지가 보인다. 이 중 실제 우리가 원하는 pts만 골라내기 위해 아랫줄의 결과는 버리자.
ps -ef | grep sshd | grep pts/0 | head -1 
  1. 위와 같은 결과에서 gawk를 사용하면 한 행에 있는 각 열을 각각 $1 부터 각각의 위치 변수에 담을 수 있다.
ps -ef | grep sshd | grep pts/0 | head -1 | gawk '{print $2}'
  1. 해당 ip의 ssh 프로세스를 kill하기
kill -9 1490 

해당 ip의 접속 끊기

#!/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

해당 ip의 접속을 차단하기

#!/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
  • 접속하지 않은 ip를 입력하면 아래와 같이 출력
  • 접속된 ip를 입력하면 차단됨

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

KVM 환경 구성

실습
사용자로부터 값을 입력 받아 가성머신 생성하기

  1. KVM 관련 패키지 설치
yum -y install qemu-kvm virt-install libvirt virt-manager libguestfs-tools 
  1. kimchi 설치(kimchi는 fedora에서 동작한다) -> wokd를 통해 kimchi에 접속
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 로 접속

  1. qemu.conf 수정
vi /etc/libvirt/qemu.conf

442째 줄 user="root" -> 해시 제거
446째 줄 group = "root" -> 해시 제거

  1. kvm 재실행
systemctl daemon-reload 
systemctl restart wokd 
systemctl restart libvirtd 
systemctl enable libvirtd 
  1. CentOS7 이미지 받기
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
  1. 생성된 이미지에 강제로 root 패스워드 설정하기
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문

기본 형태

for 변수 in 리스트 
do 
    commands 
done 

IFS(Internal Field Separator)

set | grep IFS

cat /etc/passwd | grep user1

  • IFS를 콜론(:)으로 설정하여 문자열 슬라이싱하기
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 원래대로 다시 돌려 놓기
IFS=$' \t\n'

gawk로 IFS 임시 설정하기

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 - 전체 인스턴스 생성 프로그램 만들기

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

profile
take a look

0개의 댓글