[에스넷시스템 부트캠프] TIL Day 19 - 스크립트, 반복문, 조건문, 원격지 접근 자동화 스크립트

2025. 6. 16. 22:53·TIL
728x90

1. 스크립트

1) 스크립트란?

명령어를 순서대로 자동 실행하도록 작성한 텍스트 파일을 말한다. 반복적인 작업을 자동화하여 효율을 높이는 데 많이 이용된다. 

  • 컴파일 언어 : .c -> gcc 등으로 바이너리 파일로 컴파일 후 실행 ex) C++
  • 인터프리터 언어 : 소스 코드를 인터프리터가 한 줄씩 해석하여 실행 ex) Python, Bash

# cat /etc/shells 명령어를 통해 시스템에 설치된 쉘(interpreter) 목록을 확인할 수 있다. 

 

2) 쉘 종류

  • sh : 오리지날 쉘, 부팅시에 실행되는 스크립트는 sh를 이용
  • bash : 리눅스에 기본 탑재, 왠만한 배포판에는 bash를 이용중
  • csh : c언어 기능을 탑재
  • tcsh :  c쉘이 발전
  • ksh : aix , hp_ux 쪽에서 사용
  • zsh : 그 이후 개발된 쉘
  • fish : 그 이후 개발된 쉘
  • dash : ubuntu 6.06 이후 탑재 [사용자 기능이 없어서 bash 기반으로 작성된 스크립트가 동작을 안할수 있음 ]

 

3) Shebang (#!)

참고로 '셔뱅'이라 읽는다...
#!/usr/bin/bash

스크립트 상단에 선언하는 인터프리터 지정 지시자로 첫 2바이트를 OS가 감지하여 뒤에 오는 경로로 실행해준다.

#로 시작하지만 주석이 아니다!

명령어로 실행하는 경우(bash run.sh)에는 Shebang이 없어도 되지만, 직접 실행하거나 자동화할 때는 적어줘야 한다. 

 

💡 리눅스에서의 확장자
리눅스에서 파일 이름에 지정해주는 확장자는 OS 수준에서는 아무런 의미가 없는 단순 관례일 뿐이다. 
실행 궈한이 있고 인터프리터가 지정되어 있다면 확장자 없이도 실행이 가능하다. 
그렇기에 외부에서 받아온 파일일 경우 # file 명령어로 파일 타입을 꼭 확인하는 습관을 들이자. 

 

6) 공용 스크립트 디렉토리 구성

다른 사용자들과 공용으로 사용할 작업 디렉토리의 경우 /usr/local/bin 밑에 새로운 디렉토리를 만들어서 작성한다. 

 

7)  명령어 실행시의 순서

  1. hash: 캐시된 명령어 우선
  2. alias: 별칭 우선
  3. $PATH 검색: PATH에 등록된 디렉토리를 하나씩 순차적으로 돌면서 ls 명령어를 찾고 실행. 가장 처음으로 찾아낸걸 실행. 스크립트용 디렉토리를 항상 뒤에 추가, 같은 이름이 있는지 먼저 검수한 뒤 파일을 작성해야 함

2. 반복문 

1) for

기본 문법 

for 변수 in 리스트; do 
	명령어
done

 

예제

for i in 1 2 3 4 ; do 
> echo $i
> done
1
2
3
4
  • $i : 현재 반복 변수 값을 참조 

awk를 이용한 예제

 

# seq -w 1 100

: 숫자 앞에 0을 붙여서 고정 길이를 유지해 001부터 100까지 숫자 리스트 생성

 

2) while

기본 문법

while true; do
    명령어
done

 

주의사항 

  • while true는 무한 루프이기 때문에 sleep 구문을 꼭 넣어줘야 CPU 사용률 폭주를 막을 수 있다.
  • 루프 자체는 top 명령어에서 돌아가고 있는지 확인이 어려울 수 있다. 
  • Ctrl+C를 누르기 전까지는 무한정 돈다는 단점이 있다.

 

3) 두 반복문의 결합 스크립트

#!/usr/bin/bash

hosts_file="hosts_output.txt"
prefix="13.13.13."
domain_name=".example.com"
start=1
end=254

current_ip=${start}

while [ ${current_ip} -le ${end} ]; do
        for host_number in $(seq ${current_ip} ${end}); do
                echo "${prefix}${host_number}  host${host_number}${domain_name}  host${host_number}" >> $hosts_file
        done
        current_ip=$((current_ip + 1))
done


echo "hosts file update"

 

  • while: IP 범위 (start~end)를 컨트롤
  • for: 각 host_number에 대해 한 줄씩 생성
  • >>: 결과를 파일에 덧붙이기
  • ${}: 변수 참조
  • $(()): 산술 연산 (e.g. +1)
  • $(): 명령어 결과 치환 (e.g. seq)

출력 예

13.13.13.1  host1.example.com  host1
13.13.13.2  host2.example.com  host2
...

 

3. 조건문

기본 문법

if [ 조건 ]; then
    명령어
elif [ 다른 조건 ]; then
    명령어
else
    명령어
fi

 

if [ $? = 0 ]; then

: 직전에 실행한 명령어의 종료 상태($?)가 0인지 확인

성공이면 0, 실패면 0이 아님

 

4. 원격지 접근 자동화 스크립트

보안성과 확장성을 고려한 SSH 키 자동 생성, 배포 및 테스트까지 수행하는 스크립트를 구현한다. 

 

요구사항

  1. 비밀번호 키가 남아 있으면 안된다.
  2. 이후 접속에 비밀번호 입력안하고 사용 가능해야 한다.
  3. sshpass가 없다면 설치 -> if [ -f /usr/bin/sshpass ]
  4. 파일이 있으면 그냥 패스! 없으면 설치 후 진행
  5. vm2.exmaple.com에 인증키를 배포하는 단 하나의 파일로 구성

 

한글로 작성한 수도코드

  1. sshpass 유무 확인 
  2. 인증키 유무 확인
  3. 인증키 생성
  4. 비밀번호 파일 구성
  5. 내보내기
  6. 비밀번호 파일 삭제
  7. 디렉토리 삭제
  8. 정상적으로 동작하는지 테스트 : ssh root@10.10.10.20 "hostname" 

 

구현 코드

#!/usr/bin/bash

# Custom value
#TARGET_IP="10.10.10.20"
#TARGET_USER="root"
#PASS_FILE="password"
#PASS_TEXT="rocky"
#rm -rf ${HOME}/.ssh

#0. input value
while true; do
        read -p "Enter target ip: " TARGET_IP
        read -p "Enter target user: " TARGET_USER
        echo ""
        echo "[CHECK] IP:${TARGET_IP}, USER_NAME:${TARGET_USER}"
        read -p "is this correct? (yes/no): " confirm

        if [[ "$confirm" == "yes" ]]; then
                break
        else
                echo "[INFO] please re-check IP and username"
        fi
done

while true ; do 
        read -sp "Enter ssh password: " pass_text1
        echo ""
        read -sp "Re-enter ssh password: " pass_text2
        echo "" 

        if [ "$pass_text1" == "$pass_text2" ]; then
                PASS_TEXT=${pass_text1}
                break
        else
                echo "[WARN] password do not match" >&2
        fi
done

PASS_FILE="password"

#1. check if sshpass is installed
if [ ! -f /usr/bin/sshpass ]; then
        echo "[INFO] sshpass command is not found. installing.." 
    dnf -y install sshpass || { echo "[ERROR] could not install sshpass" >&2 ; exit 1; }
fi

#2. sshkey if not exist
if [ ! -f "${HOME}/.ssh/id_rsa" ]; then
        echo "[INFO] not found id_rsa eky. making a new id_rsa.." 
    ssh-keygen -f ${HOME}/.ssh/id_rsa -N '' -t rsa -b 4096 > /dev/null
 fi

#3. make password file
echo ${PASS_TEXT} > ${PASS_FILE}
chmod 400 ${PASS_FILE}

#4. copy ssh key using password
sshpass -f ${PASS_FILE} ssh-copy-id -o StrictHostKeyChecking=no -f ${TARGET_USER}@${TARGET_IP}

#5. delete password file safely
if [ -f ${PASS_FILE} ; then
        echo "[INFO] delte password file"
        shred -u ${PASS_FILE}
fi

#6. check remote host ssh connection words (run hostname check)
echo "[INFO] test ssh connection"
ssh -o StrictHostKeyChecking=no ${TARGET_USER}@${TARGET_IP} 'hostname' > /dev/null
if [ $? -eq 0 ]; then
        echo "[INFO] ssh test OK"
 else
    echo "[INFO] ssh test FAIL"
  fi


unset TARGET_IP
unset TARGET_USER
unset PASS_FILE
unset PASS_TEXT

 

# read -p "텍스트" 변수

: 입력 받은 값을 변수에 저장

 

# read -sp "텍스트" 변수

: 입력값을 화면에 표시하지 않음 (s = silent)

 

# ssh-keygen

: SSH 키 생성

 

# ssh-copy-id [사용자계정]@[IP주소]

: 패스워드를 적을 때 IP 주소에 해당하는 서버의 비밀번호를 자동 입력

 

# ssh-copy-id -o StrictHostKeyChecking=no root@10.10.10.20

: 등록은 가능 하지만 여전히 비밀번호를 한번 입력해야 함

 

권한이 400인 password 파일 생성

-> sshpass -f password ssh-copy-id -o StrictHostKeyChecking=no root@10.10.10.20 

: 비밀번호 입력 없이 수행 ssh 접근

작업 이후에는 비밀번호로 사용된 파일은 삭제하자. 

 

# shred -u 파일명

: 내용을 다른걸로 덮어씌우고 삭제하는 방식으로 민감한 정보가 들어 있는 파일을 삭제할 때 주로 사용됨 

 

💡 Bash 변수 대소문자 네이밍 관례
수업을 듣다가 왜 처음에 정의한 변수는 대문자로만 적고, 입력으로 받은 값을 저장하는 변수는 소문자로 적는지에 대한 의문이 들었다. 문법이 정해져 있는 건가 했으나 단순 관례라고 한다.

스크립트 내에서 한정된 범위에서만 사용되는 로컬/임시 변수는 소문자로, 외부에서 참조할 수도 있고 스크립트에서 전역적으로 쓰이는 전역 상수/환경 변수는 대문자로 쓰는 것이 일반적인 관례이다. 

 

✍️ 하루 회고

오늘은 리눅스 스크립트 작성과 관련된 내용을 중심으로 학습했다.
고등학교 때부터 익숙하게 다뤘던 반복문과 조건문이 나와서 비교적 수월하게 따라갈 수 있었다.

이번 강의를 통해 스크립트가 단순한 명령어의 나열이 아니라, 반복적이고 불필요한 작업을 줄여주는 강력한 도구라는 점을 다시금 실감했다. 앞으로도 스크립트 작성법을 꾸준히 익혀서, 자동화를 통해 업무 효율을 높일 수 있는 엔지니어로 성장하고 싶다.

 

 

728x90

'TIL' 카테고리의 다른 글

[에스넷시스템 부트캠프] TIL Day 21 - Ansible 문법  (2) 2025.06.19
[에스넷시스템 부트캠프] TIL Day 20 - IaC, Ansible 기초  (0) 2025.06.17
[에스넷시스템 부트캠프] TIL Day 18 - Crontab, autofs, swap  (0) 2025.06.14
[에스넷시스템 부트캠프] TIL Day 17 - NTP, DNF  (0) 2025.06.12
[에스넷시스템 부트캠프] TIL Day 16 - LVM  (0) 2025.06.12
'TIL' 카테고리의 다른 글
  • [에스넷시스템 부트캠프] TIL Day 21 - Ansible 문법
  • [에스넷시스템 부트캠프] TIL Day 20 - IaC, Ansible 기초
  • [에스넷시스템 부트캠프] TIL Day 18 - Crontab, autofs, swap
  • [에스넷시스템 부트캠프] TIL Day 17 - NTP, DNF
yulee_to
yulee_to
  • yulee_to
    yulee
    yulee_to
  • 전체
    오늘
    어제
    • 전체 글 (144)
      • CS (2)
        • OS (0)
        • DB (0)
        • Network (2)
      • Develop (21)
        • Spring (9)
        • Java (12)
        • Python (0)
        • Algorithm (0)
        • 기타 (0)
      • PS (39)
        • C++ (39)
        • Java (0)
      • TIL (37)
      • Book (39)
        • 자바의 신 (32)
        • 스프링 입문을 위한 자바 객체 지향의 원리와 이해 (7)
      • ETC (4)
        • Blog (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    EC2
    Java
    aws
    클라우드 활용 네트워크 엔지니어 부트캠프
    자바의 신
    스터디
    자바
    boj
    알고리즘
    TiL
    에스넷시스템
    1일1백준
    스프링 입문
    멀티캠퍼스it부트캠프
    GodOfJava
    부트캠프후기
    객체지향
    백준
    C++
    에스넷시스템 부트캠프
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
yulee_to
[에스넷시스템 부트캠프] TIL Day 19 - 스크립트, 반복문, 조건문, 원격지 접근 자동화 스크립트
상단으로

티스토리툴바