리눅스 쉘 기본 정리2

양승현·2022년 7월 26일
0

linux

목록 보기
10/20

변수

  • 임시로 값을 저장하여 활용할 수 있는 저장공간
환경 변수 
- 사용자가 리눅스 시스템에 로그인을 하게 되면 해당 환경내에서 자동으로 부여되는 변수, 시스템 전체에 영향을 미친다.
[root@gildong ~]# set | grep IFS
IFS=$' \t\n'
* IFS 는 사용자가 쉘 사용시 각각의 데이터를 구분하는 구분자
사용자 변수 
- 사용자가 직접 만들어서 사용하는 변수, 해당 파일에서만 영향을 미친다.  env, printenv, set   
bash 에서는 변수를 미리 지정할 필요없고, 데이터타입을 지정할 필요도 없다. 
변수 선언과 동시에 값을 지정한다. bash 는 모든 변수값이 str 이다. 
name=hello  -> name = hello (x, 명령어 name 에 =, hello 라는 옵션을 적용한 것으로 취급)
name="hello all"

배열(리스트)

  • 같은 타입의 변수들로 이루어진 유한 집합
name[1] = "gildong" 연관배열(딕셔너리)
  • 배열은 번호를 이용하고 연관배열은 키:value를 이용하므로
    배열은 인덱싱이 가능하다. 자료검색, 관리등에 유용하다. 또한 연관배열은 json 형태와 유사하게 key: value 를 사용하므로 다른 프로그래밍 언어들과 연계하여 사용하기가 유용하다. -> NoSQL 에 자료관리가 유용하다.
  • bash 에서도 동일하게 변수, 배열, 연관배열의 사용이 가능하다.
#!/bin/bash
echo "사용자 이름 : " $USER
echo "홈 디렉토리 : " $HOME
exit 0   <--- 종료 코드를 강제로 "0" 으로 설정하겠다.
[root@gildong ~]# echo $?  <--- 직전 실행한 코드, 명령의 종료 상태를 반환
sh -> /bin/bash 에 링크 걸려 있음
sh -> bash 를 실행하는 것과 동일하다. 
sh test1.sh
  • 파일에 실행권한을 부여하고 동작하도록 하고 싶다면?
파일 실행
1. bash test1.sh 또는 sh test1.sh
2. chmod +x test1.sh ; ./test1.sh  <<< *

명령치환하기 *

명령의 결과를 변수/file에 담아 활용하기

test1=`date`
test2=$(date)    <---- * 
[root@yangseunghyun 0726]# test1=$(date +%y%m%d%H%M)
[root@yangseunghyun 0726]# echo $test1
2207261008
[root@yangseunghyun 0726]# date > test1.txt
[root@yangseunghyung 0726]# cat test1.txt
Tue Jul 26 10:10:05 KST 2022

임시파일 활용하기

[root@yangseunghyun 0726]# test1=$(mktemp /tmp/hello.XXXXXX)
[root@yangseunghyun 0726]# echo $test1
/tmp/hello.RXBxt8
[root@yangseunghyung 0726]# test1=$(mktemp /tmp/hello.XXXXXX)
[root@yangseunghyun 0726]# echo $test1
/tmp/hello.RXBxt8
[root@yangseunghyun 0726]# test1=$(mktemp /tmp/hello.XXX)
[root@yangseunghyun 0726]# echo $test1
/tmp/hello.rf8

계산하기

    1. expr
expr 10 + 2
expr 10 - 2
expr 10 / 2
expr 10 % 2 -> 나머지 0이 출력
expr 10 * 2 -> *를 패턴과 혼동할 수 있으므로 계산이 되지 않는다
[root@yangseunghyun 0726]# expr 10 \* 2 <--- 우리는 무조건 계산 * 앞에는 \를 붙인다.
20
[root@yangseunghyung 0726]#   <- 모든 배포판 리눅스에서 \ 를 붙여야하는 것은 아니다. 
[root@yangseunghyung 0726]# res1=`expr 10 + 2`
[root@yangseunghyung 0726]# echo $res1
12
[root@yangseunghyung 0726]# res2=$(expr 10 + 2)
[root@yangseunghyung 0726]# echo $res2
12
[root@yangseunghyung 0726]# res3=$[ 10 + 2 ]
[root@yangseunghyung 0726]# echo $res3
12
  • 계산 결과를 환면에 출력하고 싶다면 '계산식'
  • 하지만 $[ 계산식 ]을 쓰면 출력이 아니라 결과값을 명령으로 실행하게 되므로 대괄호의 계산식은 반드시 변수와 함께 사용하야 한다.
변수명=$[ 계산식 ]
  • 실수 계산을 위해서는 bash caculator 가 필요하다.
[root@yangseunghyun 0726]# bc -q
5/4
1
scale=2
5/4
1.25
var1=10
var1 * 4
40
print var1
10
quit
  • bc를 이용한 계산결과 활용하기
변수명=$(echo "옵션; 계산식" | bc)
[root@yangseunghyun 0726]# var1=$(echo "scale=4; 3.14 * 3" | bc) ; echo $var1
9.42
  • 파라미터 변수(위치변수), 매개변수(함수내로 전달하는 변수)로도 활용가능
dnf -y install httpd
"dnf"는 패키지를 설치하는 명령어
예)
[root@yangseunghyun 0726]# echo hello hi dd ff aa
hello hi dd ff aa 
 $1,  $2,$3,$4,$5
  • 파라미터 변수는 명령과 옵션등을 변수로 활용할 수 있다.
test2.sh gildong 24 용인 
test2.sh chulsoo 25 서울 
$1 은 DB 저장할 때 테이블의 첫번째 열에 저장해라
$2 는 DB ..                         
두번째 열에 저장해라.

전체는 (* (@ 도 사용한다)


조건문

if 문

if 명령 또는 [ 조건 ] -> [ "woo" = "woo" ]
then
	참일 경우
else
	거짓일 경우
fi
  • 조건 대신 명령이 들어가면 명령이 정상적으로 실행되었을 때가 참이 된다.
  • 사용자로부터 검색하고 싶은 사용자의 이름을 입력받고 해당 사용자가 있다면 화면에 결과를 출력하라.

quiz.

사용자로 부터 httpd 가 설치되어 있는지 여부를 확인하고 설치되어 있지 않다면 해당 패키지를 설치하도록 하라. 만약 설치되어 있다면 버전을 출력하고 그렇지 않다면 설치하는 프로그램을 작성하세요!!
rpm -qa | grep httpd <--- httpd 패키지 설치 여부 확인

검색하고 싶은 패키지? : httpd
설치되어 있지 않다. 
설치가 진행됨

검색하고 싶은 패키지? : httpd
설치되어 있음.
httpd 버전 출력

[실습 문제]

  • 원격지에 접속한 특정 사용자의 ssh 연결을 종료시켜라
접속을 종료 시키고 싶은 IP를 입력하시오 : 192.168.1.99
해당 IP는 없습니다.
또는
연결을 종료 시켰습니다.

[정답]

#!/bin/bash
# 변수 선언
ipaddr=''
# 검색할 IP 주소 요청
echo -n "차단할 IP 주소 입력 : "
read ipaddr
if who | grep $ipaddr
then
        pts=$(who | grep $ipaddr | gawk '{print $2}')
        pid=$(ps -ef | grep sshd | grep $pts | gawk '{print $2}')
        kill -9 $pid
else
        echo "해당 사용자는 접속하지 않았음"
fi

[root@yangseunghyun 0726]# yum -y install net-tools
# route del -host $ipaddr reject << 해제

  • 접속된 사용자 확인 가능!
[root@yangseunghyun 0726]# who
root     tty1         2022-07-26 09:25
root     pts/1        2022-07-26 09:25 (192.168.1.99)
root     pts/2        2022-07-26 08:49 (192.168.1.70)
root     pts/3        2022-07-26 10:03 (192.168.1.70)
[root@yangseunghyun 0726]# who | grep 192.168.1.99
root     pts/1        2022-07-26 09:25 (192.168.1.99)
[root@yangseunghyun 0726]# ps -ef | grep sshd
            PID
root      12368    974  0 09:25 ?        00:00:01 sshd: root@pts/1
  • 해당 PID 를 종료해 본다.
    kill -9 12368
    [root@yangseunghyun ~]# ps -ef | grep sshd | grep pts/0 | head -1 | gawk '{print $2}'
    12832
    1. ps -ef | grep sshd -> 현재 내 시스템에서 동작하는 프로세스 중 sshd 관련 프로세스를 출력하라
    1. | grep pts/0 -> 1. 의 결과중 pts/0 과 매치하는 행이 있다면 출력하라
    1. | head -1 -> 앞선 결과는 실제 pts/0 과 grep 명령어에서 pts/0 을 사용하는 것 두가지가 보인다. 이중 실제 우리가 원하는 pts 만 골라내기 위해 아래의 결과는 버렸다.
ps -ef | grep sshd | grep pts/0 | head -1
root      12832    974  0 11:49 ?        00:00:00 sshd: root@pts/0
위와 같은 결과에서 gawk 를 사용하면 한 행에 있는 각 열을 각각 $1 부터 각각의 위치변수에 담을 수 있다. 
 | gawk '{print $2}'
    1. kill -9 12837
연결을 종료하고 싶은 IP를 입력하세요 : 192.168.1.13

결과(잘못된 IP 입력시)
해당 IP는 연결 정보가 없습니다.

결과(정상 연결된 IP가 있다면)
해당 연결을 종료하였습니다.

조건식 부분을
[] && []

  • 두 조건을 모두 만족하면 참

[] || []

  • 두 조건중 하나라도 만족하면 참

[[ == r* ]]

  • 이중 대괄호
  • "==" 는 오른쪽에서 패턴 사용가능

[실습]

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

(환경구성)

    1. KVM 관련 패키지 설치
yum -y install qemu-kvm virsh 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
systemctl enable wokd
systemctl restart wokd

이후 https://서버IP:8001 로 접속

3.
[root@gildong 0726]# vi /etc/libvirt/qemu.conf

442 user = "root"    # 제일 앞에 있는 해시 제거
446 group = "root"  # 제일 앞에 있는 해시 제거

4. kvm 재 실행

sysetmctl daemon-reload
systemctl restart wokd
systemctl restart libvirtd
systemctl enable libvirtd

5. 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

[ 실습 ]

  • 가상머신 생성 프로그램
  1. OS 선택 (1. centOS7, 2. Ubuntu18.04..) : (실습시에는 1만 선택)

  2. 가상머신의 이름을 입력하세요 : gildong (CentOS7-Base.qcow2 --복사--> gildong.qcow2)
    만약 인스턴스의 이름을 입력하지 않는다면, 화면에는 "이름이 입력되지 않았습니다. 종료됩니다" 가 출력되고 프로그램은 종료된다. 이미지 복사 작업 이루어지지 않는다.

  3. CPU 개수 선택 : 1~4 (실습시에는 1만 선택)

  4. RAM 사이즈 선택 : 1~4 (실습시에는 1만 선택) -> 1 * 1024MB -> 1024

  5. 설치가 진행됩니다. 하고 종료되도록 (virsh list --all) <-- 설치된 모든 인스턴스 확인

해설(스크립트)

-------------- 인스턴스 생성 ---------------------
#!/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

실행 권한 부여
[root@yangseunghyun 0726]# chmod +x yang.sh
실행
[root@yangseunghyun 0726]# ./yang.sh

직접 타이핑

[root@yangseunghyun cloud]# cp CentOS7-Base.qcow2 gildong.qcow2
[root@yangseunghyun cloud]# virt-install --name gildong --vcpus 1 --ram 1024 --network network:default,model=virtio --disk gildong.qcow2 --import --noautoconsole
혹시 이미 존재한다면
virsh destroy gildong
virsh undefine gildong 
한 다음 위의 명령을 다시 실행한다.

[root@yangseunghyun cloud]# virt-install --name chulsoo --vcpus 1 --ram 1024 --network network:default,model=virtio --disk chulsoo.qcow2 --import --noautoconsole > /dev/null
  • 편집기를 통해 상세내용 확인 및 ip 확인
[root@yangseunghyun 0726]# virsh list --all
[root@yangseunghyun 0726]# virsh edit gildong
  • 강제 종료 및 디스크를 삭제하면서 인스턴스 삭제하기
[root@yangseunghyun 0726]# virsh destroy gildong
Domain gildong destroyed
[root@yangseunghyun 0726]# virsh destroy chulsoo
Domain chulsoo destroyed
[root@yangseunghyun 0726]# virsh undefine gildong --remove-all-storage
Domain gildong has been undefined
Volume 'hda'(/cloud/gildong.qcow2) removed.
[root@yangseunghyun 0726]# virsh undefine chulsoo --remove-all-storage
Domain chulsoo has been undefined
Volume 'hda'(/cloud/chulsoo.qcow2) removed.
for 문
기본형태
for num in 1 2 3 
do
 echo $num
done
 list : user1
 list : X
 list : 1000
 list : 1000

[root@yangseunghyun 0726]# for list in $(cat /etc/passwd | grep user1)
do echo "list:$list" ; done
list:user1:x:1000:1000:user1:/home/user1:/bin/bash
[root@yangseunghyun 0726]# #위는 IFS 에 : 가 포함되지 않은 경우 입니다.

[root@yangseunghyun 0726]# 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

[실습] 전체 인스턴스 관리 명령어 만들기

step1. 2개의 인스턴스 생성

[root@yangseunghyun 0726]# virsh list --all

만약 --all이 빠지면 중지중인 인스턴스는 확인되지 않는다.

[root@yangseunghyun 0726]# virsh list --all | grep -v Id

[root@yangseunghyun 0726]# virsh list --all | grep -v Id | gawk '{print $2}'

file 이름 -> allvm을 만들고
allvm start -> 모든 인스턴스가 실행 (virsh start yang1)
allvm destroy -> 모든 인스턴스가 중지 (virsh destroy yang1)
allvm undefine -> 모든 인스턴스가 삭제됨 (virsh undefine yang1)

allvm -> $PATH

[풀이 예]

touch /usr/bin/allvm
chmod +x /usr/bin/allvm

[root@yangseunghyun ~]# allvm start
[root@yangseunghyun ~]# allvm destroy
[root@yangseunghyun ~]# allvm undefine
#!/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

0개의 댓글