Linux 서버를 운영하다 보면 반복적으로 수행해야 하는 작업이 계속 발생합니다.
매일 특정 디렉터리의 로그를 확인하고, 오래된 파일을 삭제하고, 디스크 사용량을 확인하고, 서비스가 정상적으로 실행되고 있는지 점검하고, 중요한 데이터를 백업해야 합니다.
서버가 한두 대라면 관리자가 직접 명령어를 실행할 수 있습니다. 하지만 서버가 수십 대, 수백 대로 늘어나면 사람이 직접 모든 서버를 관리하는 것은 현실적으로 어렵습니다.
이때 필요한 것이 Bash Shell과 Shell Script를 이용한 시스템 자동화입니다.
Shell Script는 단순히 명령어를 여러 줄 작성하는 기술이 아닙니다. 시스템 엔지니어가 반복적인 운영 작업을 자동화하고, 장애를 사전에 발견하며, 서버 운영 시간을 줄이는 가장 기본적인 자동화 기술입니다.
이번 글에서는 Linux Shell의 기본 개념부터 Bash Script 작성, 조건문과 반복문, 로그 관리, 백업, 서비스 점검, Cron을 이용한 스케줄링, 실무 자동화 사례까지 단계적으로 알아보겠습니다.
Linux에서 사용자가 운영체제와 명령어를 주고받을 수 있도록 해주는 프로그램을 Shell이라고 합니다.
사용자가 터미널에서 다음과 같이 명령어를 입력하면
ls
Shell이 이 명령어를 해석하고 운영체제에 실행을 요청합니다.
구조를 단순화하면 다음과 같습니다.
사용자
↓
Terminal
↓
Shell
↓
Linux Kernel
↓
Hardware
Shell은 사용자와 Linux Kernel 사이에서 명령어를 해석하는 역할을 합니다.
대표적인 Shell에는 다음과 같은 종류가 있습니다.
sh
bash
zsh
ksh
fish
Linux 서버 환경에서는 **Bash(Bourne Again Shell)**가 가장 널리 사용됩니다.
특히 시스템 엔지니어라면 Bash를 기본적인 서버 운영 언어로 생각하고 익혀두는 것이 좋습니다.
Bash는 Linux와 Unix 계열 운영체제에서 널리 사용되는 Shell입니다.
현재 사용 중인 Shell은 다음 명령어로 확인할 수 있습니다.
echo $SHELL
또는
ps -p $$
일반적으로 다음과 같은 결과를 볼 수 있습니다.
/bin/bash
Bash에서는 단순한 명령어 실행뿐 아니라 변수, 조건문, 반복문, 함수 등을 사용할 수 있습니다.
따라서 Bash를 이용하면 다음과 같은 작업을 자동화할 수 있습니다.
파일 관리
로그 정리
백업
서비스 점검
디스크 점검
프로세스 확인
서버 상태 확인
장애 감지
가장 간단한 Shell Script를 만들어 보겠습니다.
vi hello.sh
다음 내용을 입력합니다.
#!/bin/bash
echo "Linux Shell Script Test"
실행 권한을 부여합니다.
chmod +x hello.sh
실행합니다.
./hello.sh
결과는 다음과 같습니다.
Linux Shell Script Test
여기서 첫 번째 줄의
#!/bin/bash
는 매우 중요합니다.
이를 Shebang이라고 하며 해당 스크립트를 어떤 인터프리터로 실행할 것인지 지정합니다.
Shell Script에서는 변수를 사용할 수 있습니다.
#!/bin/bash
NAME="Linux"
echo "Hello $NAME"
결과:
Hello Linux
시스템 자동화에서는 변수 사용이 매우 중요합니다.
예를 들어 로그 디렉터리를 변수로 지정할 수 있습니다.
LOG_DIR="/var/log"
그리고 다음과 같이 사용할 수 있습니다.
ls -lh "$LOG_DIR"
변수를 사용하면 나중에 경로를 변경할 때 스크립트 전체를 수정할 필요가 줄어듭니다.
Shell Script의 강력한 기능 중 하나가 명령어의 결과를 변수에 저장하는 것입니다.
HOSTNAME=$(hostname)
또는
DATE=$(date)
이후 다음과 같이 사용할 수 있습니다.
echo "Server: $HOSTNAME"
echo "Time: $DATE"
서버 상태를 자동으로 수집하는 스크립트를 작성할 때 매우 자주 사용하는 방식입니다.
자동화에서는 상황에 따라 다른 작업을 수행해야 하는 경우가 많습니다.
이때 if 조건문을 사용합니다.
if [ -f /etc/passwd ]; then
echo "파일이 존재합니다."
else
echo "파일이 없습니다."
fi
서버 운영에서는 파일 존재 여부뿐만 아니라 서비스 상태, 디스크 사용량, 프로세스 존재 여부 등을 확인할 때 사용할 수 있습니다.
예를 들어 디스크 사용량이 높은 경우 경고를 출력하도록 만들 수 있습니다.
USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$USAGE" -ge 80 ]; then
echo "WARNING: Disk usage is ${USAGE}%"
fi
이것이 바로 시스템 자동화의 기본적인 형태입니다.
Shell Script에서는 반복문도 사용할 수 있습니다.
예를 들어 특정 디렉터리의 로그 파일을 확인하려면 다음과 같이 작성할 수 있습니다.
for file in /var/log/*.log
do
echo "$file"
done
반복문을 활용하면 수십 개의 파일을 하나씩 직접 처리하지 않고 자동으로 처리할 수 있습니다.
예를 들어 백업 대상 파일을 반복적으로 압축하거나 특정 조건에 해당하는 파일을 검색하는 작업 등에 활용할 수 있습니다.
시스템 엔지니어가 자주 작성하는 자동화 작업 중 하나가 오래된 로그 파일 관리입니다.
예를 들어 30일 이상 된 특정 파일을 찾으려면 다음과 같은 명령어를 사용할 수 있습니다.
find /var/log -type f -mtime +30
실제로 삭제할 때는 삭제 대상과 조건을 충분히 확인한 후 실행해야 합니다.
find /backup -type f -mtime +30 -delete
운영 서버에서는 이런 명령어를 바로 실행하기보다 먼저 검색 결과를 확인하는 것이 중요합니다.
find /backup -type f -mtime +30
결과가 예상과 일치하는지 확인한 후 삭제 작업을 자동화하는 것이 안전합니다.
Shell Script는 백업 자동화에도 매우 유용합니다.
예를 들어 특정 디렉터리를 압축하여 백업할 수 있습니다.
#!/bin/bash
BACKUP_DIR="/backup"
SOURCE_DIR="/data"
DATE=$(date +%Y%m%d)
tar -czf "$BACKUP_DIR/data_$DATE.tar.gz" "$SOURCE_DIR"
실행하면 다음과 같은 백업 파일을 만들 수 있습니다.
data_20260819.tar.gz
날짜를 자동으로 파일명에 넣으면 백업 파일을 구분하기 쉽습니다.
백업은 단순히 파일을 복사하는 것으로 끝나지 않습니다.
백업 서버의 저장공간도 계속 증가하기 때문입니다.
예를 들어 다음과 같은 정책을 만들 수 있습니다.
매일 백업
↓
30일 보관
↓
30일 초과 백업 삭제
Shell Script와 find를 조합하면 오래된 백업 파일을 자동으로 정리할 수 있습니다.
find /backup -type f -name "*.tar.gz" -mtime +30 -delete
하지만 실제 운영 환경에서는 삭제 전에 대상 파일을 확인하고, 백업 성공 여부를 검증하는 절차를 추가하는 것이 좋습니다.
Linux 서버에서는 systemctl을 이용해 서비스 상태를 확인할 수 있습니다.
예를 들어 Nginx를 확인합니다.
systemctl is-active nginx
결과가
active
라면 정상적으로 실행되고 있는 것입니다.
이를 Shell Script와 결합하면 서비스 장애를 자동으로 감지할 수 있습니다.
if systemctl is-active --quiet nginx; then
echo "Nginx is running"
else
echo "Nginx is DOWN"
fi
여기에 이메일이나 Slack, 모니터링 시스템과 연동하면 간단한 장애 알림 시스템으로 발전시킬 수 있습니다.
시스템 엔지니어가 실제로 만들어 보면 좋은 스크립트가 서버 상태 점검 스크립트입니다.
예를 들어 다음 정보를 한 번에 확인할 수 있습니다.
Hostname
현재 시간
CPU Load
Memory
Disk
Uptime
Network
주요 서비스
간단한 예제는 다음과 같습니다.
#!/bin/bash
echo "===== Server Status ====="
echo "Hostname:"
hostname
echo "Date:"
date
echo "Uptime:"
uptime
echo "Memory:"
free -h
echo "Disk:"
df -h
echo "Load:"
cat /proc/loadavg
이런 스크립트를 만들어 두면 서버에 접속한 후 여러 명령어를 직접 실행할 필요 없이 한 번의 명령으로 기본 상태를 확인할 수 있습니다.
Shell Script의 장점은 Linux 명령어를 조합할 수 있다는 것입니다.
예를 들어 SSH 로그인 실패 횟수를 확인한다고 가정해 보겠습니다.
grep "Failed password" /var/log/secure | wc -l
특정 IP가 반복적으로 등장하는지 확인할 수도 있습니다.
grep "Failed password" /var/log/secure
여기에 awk, sort, uniq 등을 조합하면 공격 IP를 분석하는 간단한 스크립트를 만들 수 있습니다.
이처럼 Shell Script는 단순한 반복 작업뿐만 아니라 운영 로그 분석 자동화에도 활용됩니다.
Shell Script를 작성했다고 해서 자동화가 완성되는 것은 아닙니다.
정해진 시간에 자동으로 실행해야 한다면 cron을 사용할 수 있습니다.
Cron 설정은 다음과 같이 확인합니다.
crontab -e
예를 들어 매일 새벽 2시에 백업 스크립트를 실행하려면 다음과 같이 설정할 수 있습니다.
0 2 * * * /usr/local/bin/backup.sh
구조는 다음과 같습니다.
분 시 일 월 요일
따라서
0 2 * * *
는 매일 02시 00분을 의미합니다.
Cron은 일반 터미널 환경과 실행 환경이 다를 수 있습니다.
예를 들어 터미널에서는 정상적으로 실행되는 명령어가 Cron에서는 실패하는 경우가 있습니다.
그 이유 중 하나는 PATH 환경변수가 다르기 때문입니다.
따라서 Shell Script에서는 가능하면 명령어의 절대 경로를 사용하는 것이 좋습니다.
예를 들어
/usr/bin/find
/usr/bin/tar
/usr/bin/systemctl
과 같은 방식입니다.
또한 Cron 실행 결과를 로그로 남기는 것도 중요합니다.
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
이렇게 하면 정상적으로 실행되었는지 나중에 확인할 수 있습니다.
운영 자동화에서 가장 중요한 부분 중 하나입니다.
스크립트가 중간에 실패했는데도 계속 실행된다면 심각한 문제가 발생할 수 있습니다.
Bash에서는 다음과 같은 옵션을 활용할 수 있습니다.
set -e
명령어가 실패하면 스크립트 실행을 중단하도록 하는 방식입니다.
또한 보다 안전한 스크립트 작성에서는 다음과 같은 설정도 자주 사용됩니다.
set -euo pipefail
다만 각 옵션의 동작 특성을 이해하지 않고 무조건 사용하는 것은 좋지 않습니다.
중요한 것은 자동화 스크립트가 실패했을 때 실패 사실을 명확하게 알 수 있도록 만드는 것입니다.
자동화 작업은 사람이 직접 실행하지 않기 때문에 로그가 더욱 중요합니다.
예를 들어 다음과 같이 로그 파일을 지정할 수 있습니다.
LOG_FILE="/var/log/backup.log"
echo "$(date) Backup started" >> "$LOG_FILE"
백업이 완료되면
echo "$(date) Backup completed" >> "$LOG_FILE"
와 같이 기록합니다.
장애가 발생했을 때 로그를 확인하면 언제 작업이 시작되었고 어디에서 실패했는지 추적할 수 있습니다.
Bash를 공부한다면 단순한 예제만 작성하지 말고 실제 시스템 엔지니어 업무와 연결해서 프로젝트를 만들어 보는 것이 좋습니다.
다음 정보를 자동 출력합니다.
Hostname
CPU Load
Memory
Disk
Uptime
Network
주요 서비스 상태
30일 이상 된 로그 검색
삭제 대상 출력
오래된 로그 정리
결과 로그 저장
데이터 압축
날짜별 파일 생성
백업 성공 여부 확인
오래된 백업 삭제
로그 기록
Nginx 상태 확인
PostgreSQL 상태 확인
Redis 상태 확인
장애 발생 시 로그 기록
Disk 사용량 확인
80% 이상 경고
90% 이상 심각 경고
로그 기록
이런 프로젝트를 직접 만들어 보면 Bash의 핵심 기능을 자연스럽게 익힐 수 있습니다.
Shell Script는 강력하지만 서버가 많아지면 한계가 발생합니다.
예를 들어 서버가 1대라면
server01
에서 Shell Script를 실행하면 됩니다.
하지만 서버가 100대라면
server01
server02
server03
...
server100
각 서버에 접속해서 스크립트를 실행하는 것은 비효율적입니다.
이때 등장하는 기술이 Ansible입니다.
Ansible을 사용하면 중앙에서 여러 서버를 관리할 수 있습니다.
Ansible Controller
|
┌────────────┼────────────┐
↓ ↓ ↓
Server01 Server02 Server03
예를 들어 100대의 Linux 서버에 동일한 패키지를 설치하거나 설정 파일을 배포하고 서비스를 재시작하는 작업을 자동화할 수 있습니다.
둘 중 하나만 사용하는 것이 아니라 서로 다른 영역에서 활용한다고 생각하는 것이 좋습니다.
|
구분 |
Bash |
Ansible |
|---|---|---|
|
기본 목적 |
로컬 작업 자동화 |
여러 서버 관리 자동화 |
|
문법 |
Shell Script |
YAML |
|
파일 관리 |
강력함 |
강력함 |
|
명령어 실행 |
매우 강력함 |
가능 |
|
서버 대량 관리 |
제한적 |
매우 적합 |
|
설정 관리 |
가능 |
매우 적합 |
|
반복 작업 |
적합 |
매우 적합 |
|
운영 규모 |
소규모~중규모 |
중규모~대규모 |
Bash를 제대로 이해하면 Ansible을 배울 때도 많은 도움이 됩니다.
Ansible 역시 결국 Linux 명령어와 시스템 구조를 이해하고 있어야 제대로 사용할 수 있기 때문입니다.
시스템 엔지니어의 자동화 역량은 다음과 같이 발전할 수 있습니다.
Linux 명령어
↓
Bash Shell
↓
Shell Script
↓
Cron 자동화
↓
Ansible
↓
Git
↓
CI/CD
↓
Docker
↓
Kubernetes
↓
Terraform
↓
Cloud DevOps
처음에는 단순한 명령어 자동화로 시작하지만 결국에는 전체 인프라를 코드로 관리하는 Infrastructure as Code와 DevOps 환경으로 발전하게 됩니다.
최근에는 Ansible, Terraform, Kubernetes와 같은 자동화 도구가 많이 사용되고 있습니다.
그렇다고 Bash의 중요성이 사라진 것은 아닙니다.
오히려 Linux 시스템의 가장 가까운 곳에서 작업하기 때문에 Bash는 여전히 중요한 기술입니다.
예를 들어 서버에서 다음 작업을 해야 한다고 생각해 보겠습니다.
로그 검색
프로세스 확인
파일 검색
디스크 확인
서비스 재시작
네트워크 상태 확인
파일 압축
백업
이런 작업은 결국 Linux 명령어를 기반으로 합니다.
따라서 Bash를 제대로 이해하지 못하면 상위 자동화 도구를 사용하면서도 문제가 발생했을 때 원인을 파악하기 어려울 수 있습니다.
Bash 자동화를 시작한다면 다음 명령어를 집중적으로 익히는 것이 좋습니다.
echo
cat
grep
awk
sed
cut
sort
uniq
head
tail
find
xargs
tr
tee
그리고 시스템 관리 명령어도 함께 익혀야 합니다.
ps
top
free
df
du
lsblk
ss
systemctl
journalctl
ip
mount
tar
rsync
이 명령어들을 단순히 각각 사용하는 것에서 끝나지 않고 서로 조합하는 능력이 중요합니다.
Bash Shell과 Shell Script는 Linux 시스템 엔지니어가 자동화를 배우기 위한 가장 좋은 출발점입니다.
처음에는 다음과 같은 단순한 작업에서 시작합니다.
파일 복사
파일 삭제
로그 검색
디스크 확인
서비스 확인
이후에는
백업 자동화
로그 정리
서버 상태 점검
장애 감지
로 발전하고,
다시
Cron
↓
Bash Script
↓
Ansible
↓
Git
↓
CI/CD
↓
Docker
↓
Kubernetes
↓
Cloud
로 확장할 수 있습니다.
결국 Bash를 배우는 목적은 Shell 문법을 외우는 것이 아닙니다. 반복되는 시스템 관리 작업을 자동화하고, 사람이 실수하기 쉬운 작업을 코드로 표준화하는 것입니다.
특히 시스템 엔지니어라면 다음과 같은 사고방식을 갖는 것이 중요합니다.
“이 작업을 매번 사람이 해야 하는가?”
라는 질문을 던지고,
반복되는 작업
↓
명령어 정리
↓
Shell Script 작성
↓
로그 및 오류 처리
↓
Cron 자동 실행
↓
Ansible로 여러 서버에 확대
↓
Git으로 코드 관리
↓
CI/CD로 배포 자동화
라는 방향으로 발전시켜야 합니다.
이 과정까지 익히면 Linux 서버를 단순히 “운영하는 사람”에서 한 단계 더 나아가 운영 작업을 자동화하고 표준화할 수 있는 시스템 엔지니어로 발전할 수 있습니다.