Shell 스크립팅 실전 가이드 | Bash, Zsh, PowerShell 비교

Shell 스크립팅 실전 가이드 | Bash, Zsh, PowerShell 비교

Shell 스크립트는 반복 작업을 자동화하는 가장 빠른 방법이다. 이 글에서는 Bash, Zsh, PowerShell의 차이점과 실무에서 자주 쓰는 패턴을 다룬다.


목차

  1. Shell이란?
  2. Bash 기초
  3. Zsh와 Oh My Zsh
  4. PowerShell 기초
  5. Shell 스크립트 작성
  6. 실전 자동화 예제
  7. Shell 비교 및 선택
  8. 프로덕션 팁

사전 지식 (초보자를 위한 기초)

1. Shell이란?

Shell은 사용자와 운영체제를 연결하는 명령어 해석기다. 사용자가 입력한 명령어를 운영체제가 이해할 수 있는 형태로 변환하고, 결과를 다시 사용자에게 보여준다.

예를 들어 ls 명령어를 입력하면, Shell이 이를 해석해서 운영체제에 파일 목록 조회를 요청하고, 결과를 터미널에 출력한다.

GUI vs CLI:

아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

GUI (Graphical User Interface):
- 마우스 클릭
- 아이콘, 창
- 직관적, 느림

CLI (Command Line Interface):
- 키보드 입력
- 텍스트 명령어
- 빠름, 자동화 가능

2. 터미널 vs Shell

터미널 (Terminal)

  • Shell을 실행하는 프로그램
  • 예: iTerm2, Windows Terminal, GNOME Terminal

Shell

  • 명령어를 해석하는 프로그램
  • 예: Bash, Zsh, PowerShell

아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

┌─────────────────────────────────┐
│      Terminal (창)              │
│  ┌───────────────────────────┐  │
│  │   Shell (명령어 해석기)    │  │
│  │   $ ls                    │  │
│  │   file1.txt file2.txt     │  │
│  └───────────────────────────┘  │
└─────────────────────────────────┘

3. 기본 명령어

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 현재 디렉토리 확인
pwd
# /home/user

# 파일 목록
ls
# file1.txt  file2.txt  folder/

# 디렉토리 이동
cd folder

# 파일 내용 보기
cat file1.txt

# 파일 복사
cp file1.txt file2.txt

# 파일 이동/이름 변경
mv file1.txt renamed.txt

# 파일 삭제
rm file1.txt

# 디렉토리 생성
mkdir new_folder

# 명령어 도움말
man ls

1. Shell이란?

Shell의 역할

다음은 text를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

1. 명령어 해석
   $ echo "Hello"
   → echo 프로그램 실행

2. 파이프라인
   $ cat file.txt | grep "error" | wc -l
   → 3개 명령어 연결

3. 리다이렉션
   $ ls > output.txt
   → 출력을 파일로 저장

4. 변수 및 제어 구조
   $ for i in 1 2 3; do echo $i; done
   → 반복문

5. 스크립트 실행
   $ ./script.sh
   → 여러 명령어를 한 번에

Shell의 종류

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

Unix Shell 계열:
- sh (Bourne Shell, 1979)
- bash (Bourne Again Shell, 1989) ← 가장 보편적
- zsh (Z Shell, 1990) ← 최신 기능
- fish (Friendly Interactive Shell, 2005)

Windows:
- cmd.exe (Command Prompt, 1981)
- PowerShell (2006) ← 현대적, 강력함

기타:
- dash (Debian Almquist Shell) ← 빠름
- ksh (Korn Shell)
- tcsh (TENEX C Shell)

2. Bash 기초

Bash란?

Bash (Bourne Again Shell)는 Linux·macOS에서 흔히 쓰이는 기본 셸이다.

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Bash 버전 확인
bash --version
# GNU bash, version 5.2.15

# 현재 Shell 확인
echo $SHELL
# /bin/bash

기본 문법

변수:

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 변수 선언 (공백 없이!)
name="Alice"
age=25

# 변수 사용
echo "Name: $name, Age: $age"
# Name: Alice, Age: 25

# 명령어 결과 저장
current_date=$(date)
echo "Today: $current_date"

# 환경 변수
export PATH="/usr/local/bin:$PATH"

조건문:

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# if 문
if [ "$age" -gt 18 ]; then
    echo "Adult"
else
    echo "Minor"
fi

# 파일 존재 확인
if [ -f "file.txt" ]; then
    echo "File exists"
fi

# 디렉토리 존재 확인
if [ -d "folder" ]; then
    echo "Directory exists"
fi

# 문자열 비교
if [ "$name" = "Alice" ]; then
    echo "Hello Alice"
fi

# 숫자 비교
# -eq (equal), -ne (not equal)
# -gt (greater than), -lt (less than)
# -ge (greater or equal), -le (less or equal)

반복문:

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# for 문
for i in 1 2 3 4 5; do
    echo "Number: $i"
done

# 범위
for i in {1..10}; do
    echo $i
done

# 파일 순회
for file in *.txt; do
    echo "Processing $file"
    cat "$file"
done

# while 문
count=1
while [ $count -le 5 ]; do
    echo "Count: $count"
    count=$((count + 1))
done

함수:

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 함수 정의
greet() {
    local name=$1  # 첫 번째 인자
    echo "Hello, $name!"
}

# 함수 호출
greet "Alice"
# Hello, Alice!

# 반환값
add() {
    local result=$(($1 + $2))
    echo $result
}

sum=$(add 10 20)
echo "Sum: $sum"
# Sum: 30

3. 파이프와 리다이렉션

파이프 (|)

파이프는 앞 명령의 출력을 뒤 명령의 입력으로 이어 준다.

아래 코드는 bash를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 파일에서 "error" 찾기
cat log.txt | grep "error"

# 중복 제거 후 정렬
cat names.txt | sort | uniq

# 상위 10개 프로세스 (CPU 사용률)
ps aux | sort -k3 -r | head -10

# 파일 개수 세기
ls | wc -l

# JSON 파싱 (jq 사용)
curl https://api.example.com/users | jq '.[] | .name'

리다이렉션

출력 리다이렉션:

아래 코드는 bash를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 파일로 저장 (덮어쓰기)
echo "Hello" > output.txt

# 파일에 추가
echo "World" >> output.txt

# 에러 리다이렉션
command 2> error.log

# 출력과 에러 모두
command > output.log 2>&1

# /dev/null로 버리기
command > /dev/null 2>&1

입력 리다이렉션:

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 파일에서 입력 받기
mysql -u root -p < schema.sql

# Here Document
cat << EOF > config.txt
server {
    listen 80;
    server_name example.com;
}
EOF

4. Zsh와 Oh My Zsh

Zsh란?

Zsh (Z Shell)는 Bash를 호환하면서 확장이 많은 대안 셸이다. (macOS Catalina부터 기본)

Bash vs Zsh:

아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

Bash:
- 표준, 호환성 높음
- 기본 기능

Zsh:
- 강력한 자동 완성
- 테마 및 플러그인
- 더 나은 히스토리
- 스펠링 교정

Zsh 설치

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# macOS (기본 설치됨)
chsh -s /bin/zsh

# Ubuntu/Debian
sudo apt install zsh
chsh -s $(which zsh)

# 로그아웃 후 재로그인

Oh My Zsh 설치

Oh My Zsh는 Zsh 설정을 묶어 둔 프레임워크다.

# 설치
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# 설치 후 ~/.zshrc 파일 생성됨

Oh My Zsh 테마

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ~/.zshrc 편집
nano ~/.zshrc

# 테마 변경
ZSH_THEME="robbyrussell"  # 기본
ZSH_THEME="agnoster"      # 인기
ZSH_THEME="powerlevel10k/powerlevel10k"  # 최고 인기

# 적용
source ~/.zshrc

Powerlevel10k 설치 (추천):

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

# ~/.zshrc
ZSH_THEME="powerlevel10k/powerlevel10k"

# 설정 마법사
p10k configure

Oh My Zsh 플러그인

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ~/.zshrc
plugins=(
    git                    # Git 단축키
    zsh-autosuggestions   # 명령어 자동 제안
    zsh-syntax-highlighting  # 문법 하이라이팅
    docker                # Docker 자동 완성
    kubectl               # Kubernetes 자동 완성
    npm                   # npm 자동 완성
)

# zsh-autosuggestions 설치
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

# zsh-syntax-highlighting 설치
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

# 적용
source ~/.zshrc

Zsh 강력한 기능

1) 자동 완성:

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 디렉토리 이동 (Tab으로 자동 완성)
cd /u/l/b  # Tab → /usr/local/bin

# 명령어 옵션 자동 완성
git co  # Tab → git checkout, git commit, ...

# 파일 이름 자동 완성 (대소문자 무시)
ls doc  # Tab → Documents/

2) 히스토리 검색:

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Ctrl+R: 히스토리 검색
# 입력: git
# → 이전에 실행한 git 명령어 표시

# 히스토리 공유 (여러 터미널)
setopt share_history

3) 스펠링 교정:

$ gti status
# zsh: correct 'gti' to 'git' [nyae]? y
# → git status 실행

5. PowerShell 기초

PowerShell이란?

PowerShell은 Windows에서 널리 쓰이는 객체 중심 셸이다.

cmd.exe vs PowerShell:

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

cmd.exe (옛날):
- 텍스트 기반
- 제한적인 기능
- 레거시

PowerShell (현대):
- 객체 기반
- .NET 통합
- 강력한 스크립팅
- 크로스 플랫폼 (Linux/macOS 지원)

PowerShell 설치

아래 코드는 powershell를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Windows (기본 설치됨)
# PowerShell 7 (최신 버전) 설치
winget install Microsoft.PowerShell

# macOS
brew install powershell/tap/powershell

# Ubuntu
sudo snap install powershell --classic

# 실행
pwsh

PowerShell 기본 명령어

Cmdlet (Command-let):

아래 코드는 powershell를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 동사-명사 형식
Get-Process      # 프로세스 목록
Get-Service      # 서비스 목록
Get-ChildItem    # 파일 목록 (ls 별칭)
Set-Location     # 디렉토리 이동 (cd 별칭)
Copy-Item        # 파일 복사 (cp 별칭)
Remove-Item      # 파일 삭제 (rm 별칭)

# 별칭 확인
Get-Alias ls
# CommandType     Name
# -----------     ----
# Alias           ls -> Get-ChildItem

객체 기반 파이프라인:

아래 코드는 powershell를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Bash (텍스트 기반)
ps aux | grep chrome | awk '{print $2}'

# PowerShell (객체 기반)
Get-Process | Where-Object {$_.Name -like "*chrome*"} | Select-Object Id

# 더 간단하게
Get-Process chrome | Select-Object Id, CPU, WorkingSet

PowerShell 변수

다음은 powershell를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 변수 선언
$name = "Alice"
$age = 25

# 변수 사용
Write-Host "Name: $name, Age: $age"

# 배열
$fruits = @("Apple", "Banana", "Cherry")
$fruits[0]  # Apple

# 해시테이블
$user = @{
    Name = "Alice"
    Age = 25
    Email = "[email protected]"
}
$user.Name  # Alice
$user[Age]  # 25

6. Shell 스크립트 작성

Bash 스크립트

기본 구조:

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash
# Shebang: 어떤 Shell로 실행할지 지정

# 스크립트 설명
# 작성자: Alice
# 날짜: 2026-03-31

# 에러 발생 시 중단
set -e

# 변수
NAME="World"

# 함수
greet() {
    echo "Hello, $1!"
}

# 실행
greet "$NAME"

실행 방법:

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 실행 권한 부여
chmod +x script.sh

# 실행
./script.sh

# 또는
bash script.sh

실전 예제 1: 백업 스크립트

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# 설정
SOURCE_DIR="/home/user/documents"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="backup_$DATE.tar.gz"

# 백업 디렉토리 생성
mkdir -p "$BACKUP_DIR"

# 압축 백업
echo "Starting backup..."
tar -czf "$BACKUP_DIR/$BACKUP_FILE" "$SOURCE_DIR"

# 결과 확인
if [ $? -eq 0 ]; then
    echo "Backup successful: $BACKUP_FILE"
    
    # 7일 이상 된 백업 삭제
    find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete
    echo "Old backups cleaned"
else
    echo "Backup failed!"
    exit 1
fi

실전 예제 2: 로그 분석

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

LOG_FILE="/var/log/nginx/access.log"

echo "=== Nginx 로그 분석 ==="
echo

# 총 요청 수
total_requests=$(wc -l < "$LOG_FILE")
echo "총 요청 수: $total_requests"

# 상위 10개 IP
echo
echo "상위 10개 IP:"
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10

# 상위 10개 URL
echo
echo "상위 10개 URL:"
awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10

# HTTP 상태 코드 분포
echo
echo "HTTP 상태 코드:"
awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -rn

# 시간대별 요청 수
echo
echo "시간대별 요청 수:"
awk '{print $4}' "$LOG_FILE" | cut -d: -f2 | sort | uniq -c

실전 예제 3: 배포 자동화

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

set -e  # 에러 시 중단

PROJECT_DIR="/var/www/myapp"
BRANCH="main"

echo "🚀 배포 시작..."

# 1. Git Pull
echo "📥 최신 코드 가져오기..."
cd "$PROJECT_DIR"
git fetch origin
git reset --hard origin/$BRANCH

# 2. 의존성 설치
echo "📦 의존성 설치..."
npm ci --production

# 3. 빌드
echo "🔨 빌드..."
npm run build

# 4. 서비스 재시작
echo "🔄 서비스 재시작..."
pm2 restart myapp

# 5. 헬스 체크
echo "🏥 헬스 체크..."
sleep 5
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/health)

if [ "$response" = "200" ]; then
    echo "✅ 배포 성공!"
else
    echo "❌ 배포 실패! (HTTP $response)"
    # 롤백
    git reset --hard HEAD~1
    npm ci --production
    npm run build
    pm2 restart myapp
    exit 1
fi

7. PowerShell 스크립트

기본 문법

다음은 powershell를 활용한 상세한 구현 코드입니다. 함수를 통해 로직을 구현합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 변수
$name = "Alice"
$age = 25

# 조건문
if ($age -gt 18) {
    Write-Host "Adult"
} else {
    Write-Host "Minor"
}

# 반복문
foreach ($i in 1..5) {
    Write-Host "Number: $i"
}

# 파일 순회
Get-ChildItem *.txt | ForEach-Object {
    Write-Host "Processing $($_.Name)"
    Get-Content $_.FullName
}

# 함수
function Greet {
    param($Name)
    Write-Host "Hello, $Name!"
}

Greet -Name "Alice"

실전 예제 1: 파일 정리

아래 코드는 powershell를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/usr/bin/env pwsh

# 30일 이상 된 로그 파일 삭제
$logDir = "C:\Logs"
$daysOld = 30

Get-ChildItem -Path $logDir -Filter "*.log" | 
    Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysOld) } |
    ForEach-Object {
        Write-Host "Deleting: $($_.Name)"
        Remove-Item $_.FullName -Force
    }

Write-Host "Cleanup complete!"

실전 예제 2: 시스템 모니터링

다음은 powershell를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/usr/bin/env pwsh

# CPU 사용률
$cpu = Get-Counter '\Processor(_Total)\% Processor Time' | 
    Select-Object -ExpandProperty CounterSamples | 
    Select-Object -ExpandProperty CookedValue

Write-Host "CPU Usage: $([math]::Round($cpu, 2))%"

# 메모리 사용률
$os = Get-CimInstance Win32_OperatingSystem
$totalMemory = $os.TotalVisibleMemorySize / 1MB
$freeMemory = $os.FreePhysicalMemory / 1MB
$usedMemory = $totalMemory - $freeMemory
$memoryPercent = ($usedMemory / $totalMemory) * 100

Write-Host "Memory Usage: $([math]::Round($memoryPercent, 2))% ($([math]::Round($usedMemory, 2))GB / $([math]::Round($totalMemory, 2))GB)"

# 디스크 사용률
Get-PSDrive -PSProvider FileSystem | 
    Where-Object { $_.Used -ne $null } |
    ForEach-Object {
        $usedGB = $_.Used / 1GB
        $freeGB = $_.Free / 1GB
        $totalGB = $usedGB + $freeGB
        $percent = ($usedGB / $totalGB) * 100
        
        Write-Host "$($_.Name): $([math]::Round($percent, 2))% ($([math]::Round($usedGB, 2))GB / $([math]::Round($totalGB, 2))GB)"
    }

# 상위 10개 프로세스 (메모리)
Get-Process | 
    Sort-Object WorkingSet -Descending | 
    Select-Object -First 10 Name, @{Name="Memory(MB)";Expression={[math]::Round($_.WorkingSet / 1MB, 2)}} |
    Format-Table -AutoSize

8. 실전 자동화 예제

예제 1: Git 자동화

Bash:

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# Git 저장소 일괄 업데이트
REPOS_DIR="$HOME/projects"

for repo in "$REPOS_DIR"/*; do
    if [ -d "$repo/.git" ]; then
        echo "Updating $(basename $repo)..."
        cd "$repo"
        
        # 현재 브랜치 확인
        branch=$(git branch --show-current)
        
        # Pull
        git pull origin "$branch"
        
        # 변경사항 확인
        if [ -n "$(git status --porcelain)" ]; then
            echo "  ⚠️  Uncommitted changes"
        else
            echo "  ✅ Up to date"
        fi
        
        echo
    fi
done

예제 2: 서버 헬스 체크

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# 서버 목록
SERVERS=(
    "https://api.example.com/health"
    "https://web.example.com/health"
    "https://admin.example.com/health"
)

echo "=== Server Health Check ==="
echo "Time: $(date)"
echo

for server in "${SERVERS[@]}"; do
    response=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$server")
    
    if [ "$response" = "200" ]; then
        echo "✅ $server - OK"
    else
        echo "❌ $server - FAILED (HTTP $response)"
        
        # Slack 알림 (선택)
        # curl -X POST https://hooks.slack.com/... \
        #   -d "{\"text\":\"Server down: $server\"}"
    fi
done

예제 3: 데이터베이스 백업

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# 설정
DB_HOST="localhost"
DB_USER="admin"
DB_NAME="mydb"
BACKUP_DIR="/backup/db"
DATE=$(date +%Y%m%d_%H%M%S)

# 백업 디렉토리 생성
mkdir -p "$BACKUP_DIR"

# PostgreSQL 백업
echo "Starting database backup..."
pg_dump -h "$DB_HOST" -U "$DB_USER" "$DB_NAME" | gzip > "$BACKUP_DIR/backup_$DATE.sql.gz"

# 결과 확인
if [ $? -eq 0 ]; then
    echo "✅ Backup successful: backup_$DATE.sql.gz"
    
    # 파일 크기 확인
    size=$(du -h "$BACKUP_DIR/backup_$DATE.sql.gz" | cut -f1)
    echo "Size: $size"
    
    # 30일 이상 된 백업 삭제
    find "$BACKUP_DIR" -name "backup_*.sql.gz" -mtime +30 -delete
    
    # S3 업로드 (선택)
    # aws s3 cp "$BACKUP_DIR/backup_$DATE.sql.gz" s3://my-bucket/backups/
else
    echo "❌ Backup failed!"
    exit 1
fi

9. 유용한 명령어 모음

파일 및 디렉토리

다음은 bash를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 파일 찾기
find . -name "*.log"
find . -type f -mtime +7  # 7일 이상 된 파일

# 파일 내용 검색
grep -r "error" ./logs
grep -i "warning" file.txt  # 대소문자 무시

# 디스크 사용량
df -h
du -sh *

# 파일 권한 변경
chmod 755 script.sh
chmod +x script.sh

# 소유자 변경
chown user:group file.txt

프로세스 관리

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 프로세스 목록
ps aux
ps aux | grep nginx

# 프로세스 종료
kill <PID>
kill -9 <PID>  # 강제 종료
killall nginx  # 이름으로 종료

# 백그라운드 실행
./long_running_task.sh &

# nohup (로그아웃 후에도 실행)
nohup ./task.sh > output.log 2>&1 &

# 작업 목록
jobs

# 백그라운드 → 포그라운드
fg %1

네트워크

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 포트 확인
netstat -tulpn
ss -tulpn  # 더 빠름

# 특정 포트 사용 프로세스
lsof -i :8080

# HTTP 요청
curl https://api.example.com
curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' https://api.example.com

# 다운로드
wget https://example.com/file.zip

# DNS 조회
dig example.com
nslookup example.com

# 핑
ping -c 4 google.com

# 경로 추적
traceroute google.com

시스템 정보

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# CPU 정보
lscpu
cat /proc/cpuinfo

# 메모리 정보
free -h
cat /proc/meminfo

# 디스크 정보
lsblk
fdisk -l

# OS 정보
uname -a
cat /etc/os-release

# 시스템 부하
uptime
top
htop  # 더 보기 좋음

10. 고급 Shell 기법

명령어 치환

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# $() 사용 (권장)
current_date=$(date +%Y-%m-%d)
echo "Today: $current_date"

# 백틱 (옛날 방식)
current_date=`date +%Y-%m-%d`

# 중첩 가능
files_count=$(ls $(pwd) | wc -l)

배열

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 배열 선언
fruits=("Apple" "Banana" "Cherry")

# 접근
echo ${fruits[0]}  # Apple
echo ${fruits[@]}  # 모든 요소
echo ${#fruits[@]}  # 배열 크기

# 순회
for fruit in "${fruits[@]}"; do
    echo "$fruit"
done

# 추가
fruits+=("Date")

문자열 처리

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

text="Hello World"

# 길이
echo ${#text}  # 11

# 부분 문자열
echo ${text:0:5}  # Hello
echo ${text:6}    # World

# 치환
echo ${text/World/Bash}  # Hello Bash
echo ${text//o/0}        # Hell0 W0rld (모든 o)

# 대소문자 변환
echo ${text^^}  # HELLO WORLD (대문자)
echo ${text,,}  # hello world (소문자)

# 기본값
echo ${name:-"Guest"}  # name이 없으면 "Guest"

에러 처리

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# 에러 발생 시 중단
set -e

# 에러 발생 시 함수 호출
trap 'echo "Error on line $LINENO"' ERR

# 종료 시 정리
cleanup() {
    echo "Cleaning up..."
    rm -f /tmp/temp_file
}
trap cleanup EXIT

# 명령어 실행
if ! command -v git &> /dev/null; then
    echo "Git is not installed"
    exit 1
fi

# 명령어 성공 여부 확인
if git pull; then
    echo "Pull successful"
else
    echo "Pull failed"
    exit 1
fi

11. Shell 비교

문법 비교

변수:

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Bash/Zsh
name="Alice"
echo $name

# PowerShell
$name = "Alice"
Write-Host $name

조건문:

아래 코드는 bash를 사용한 구현 예제입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다, 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Bash/Zsh
if [ "$age" -gt 18 ]; then
    echo "Adult"
fi

# PowerShell
if ($age -gt 18) {
    Write-Host "Adult"
}

반복문:

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Bash/Zsh
for i in {1..5}; do
    echo $i
done

# PowerShell
foreach ($i in 1..5) {
    Write-Host $i
}

파이프:

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Bash/Zsh (텍스트)
ps aux | grep nginx

# PowerShell (객체)
Get-Process | Where-Object {$_.Name -eq "nginx"}

성능 비교

아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

스크립트 실행 속도 (1000번 반복, 대략적인 예):

dash:        0.5초  (가장 빠른 편)
bash:        1.2초
zsh:         1.5초
PowerShell:  3.0초

대화형 사용 (자동 완성, 플러그인):

zsh, PowerShell이 손이 많이 간다. bash는 중간. dash는 대화형보다 스크립트용에 가깝다.

기능 비교

기능BashZshPowerShell
자동 완성기본강력강력
플러그인제한적풍부풍부
객체 파이프없음없음있음
크로스 플랫폼Linux/MacLinux/MacAll
스크립트 속도빠름보통느림
학습 곡선낮음중간높음
.NET 통합없음없음있음

12. 개발 환경 설정

.bashrc / .zshrc 추천 설정

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ~/.bashrc 또는 ~/.zshrc

# 별칭 (Alias)
alias ll='ls -lah'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gpl='git pull'
alias gd='git diff'
alias gl='git log --oneline --graph --decorate'

# 함수
mkcd() {
    mkdir -p "$1" && cd "$1"
}

extract() {
    if [ -f "$1" ]; then
        case "$1" in
            *.tar.gz)  tar xzf "$1"   ;;
            *.tar.bz2) tar xjf "$1"   ;;
            *.zip)     unzip "$1"     ;;
            *.rar)     unrar x "$1"   ;;
            *)         echo "Unknown format" ;;
        esac
    fi
}

# 환경 변수
export EDITOR=vim
export VISUAL=vim
export LANG=en_US.UTF-8

# PATH 추가
export PATH="$HOME/bin:$PATH"
export PATH="/usr/local/bin:$PATH"

# 히스토리 설정
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTCONTROL=ignoredups:erasedups

# 프롬프트 커스터마이징
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

# 자동 완성
if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

PowerShell 프로필

다음은 powershell를 활용한 상세한 구현 코드입니다. 함수를 통해 로직을 구현합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# $PROFILE 파일 편집
notepad $PROFILE

# 별칭
Set-Alias ll Get-ChildItem
Set-Alias g git

# 함수
function mkcd {
    param($Path)
    New-Item -ItemType Directory -Path $Path -Force
    Set-Location $Path
}

function gs { git status }
function ga { git add $args }
function gc { git commit -m $args }
function gp { git push }

# 프롬프트 커스터마이징
function prompt {
    $location = Get-Location
    Write-Host "PS " -NoNewline -ForegroundColor Green
    Write-Host "$location" -NoNewline -ForegroundColor Blue
    return "> "
}

# 모듈 자동 로드
Import-Module posh-git  # Git 통합
Import-Module PSReadLine  # 향상된 입력

# PSReadLine 설정
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineOption -PredictionViewStyle ListView

13. 디버깅

Bash 디버깅

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 디버그 모드 실행
bash -x script.sh

# 스크립트 내에서 활성화
set -x  # 디버그 시작
# ... 코드 ...
set +x  # 디버그 종료

# 출력 예시:
# + echo 'Hello'
# Hello
# + name=Alice
# + echo 'Name: Alice'
# Name: Alice

디버깅 옵션:

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

#!/bin/bash

set -e  # 에러 시 즉시 종료
set -u  # 미정의 변수 사용 시 에러
set -o pipefail  # 파이프라인 에러 감지
set -x  # 디버그 모드

# 또는 한 줄로
set -euxo pipefail

PowerShell 디버깅

아래 코드는 powershell를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 디버그 모드
Set-PSDebug -Trace 1  # 명령어 추적
Set-PSDebug -Trace 2  # 변수 할당도 추적

# 중단점
Set-PSBreakpoint -Script script.ps1 -Line 10

# 단계별 실행
Set-PSDebug -Step

# 디버그 해제
Set-PSDebug -Off

14. 크로스 플랫폼 스크립트

플랫폼 감지

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# OS 감지
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    echo "Linux"
    package_manager="apt"
elif [[ "$OSTYPE" == "darwin"* ]]; then
    echo "macOS"
    package_manager="brew"
elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
    echo "Windows"
    package_manager="choco"
fi

# 패키지 설치
case "$package_manager" in
    apt)
        sudo apt update
        sudo apt install -y git
        ;;
    brew)
        brew install git
        ;;
    choco)
        choco install git -y
        ;;
esac

PowerShell 크로스 플랫폼

다음은 powershell를 활용한 상세한 구현 코드입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# OS 감지
if ($IsLinux) {
    Write-Host "Running on Linux"
    $packageManager = "apt"
} elseif ($IsMacOS) {
    Write-Host "Running on macOS"
    $packageManager = "brew"
} elseif ($IsWindows) {
    Write-Host "Running on Windows"
    $packageManager = "choco"
}

# 경로 구분자
$separator = [System.IO.Path]::DirectorySeparatorChar
$path = "folder$($separator)file.txt"

15. 보안 모범 사례

안전한 스크립트 작성

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# 1. 엄격 모드
set -euo pipefail

# 2. 입력 검증
if [ $# -ne 1 ]; then
    echo "Usage: $0 <filename>"
    exit 1
fi

filename="$1"

# 3. 경로 검증
if [[ "$filename" != *.txt ]]; then
    echo "Only .txt files allowed"
    exit 1
fi

# 4. 변수 인용 (공백 처리)
if [ -f "$filename" ]; then  # 인용 필수!
    cat "$filename"
fi

# 5. 임시 파일 안전하게 생성
temp_file=$(mktemp)
trap "rm -f $temp_file" EXIT

# 6. 비밀번호 입력 (숨김)
read -s -p "Password: " password
echo

비밀 정보 관리

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ❌ 스크립트에 하드코딩
DB_PASSWORD="secret123"

# ✅ 환경 변수
export DB_PASSWORD="secret123"
./script.sh

# ✅ .env 파일
# .env
DB_PASSWORD=secret123

# script.sh
source .env
echo $DB_PASSWORD

# ⚠️ .env를 .gitignore에 추가!

# ✅ 안전한 입력
read -s -p "Database password: " DB_PASSWORD
echo

16. 성능 최적화

빠른 스크립트 작성

다음은 bash를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# ❌ 느림 (외부 명령어 반복 호출)
for file in *.txt; do
    lines=$(wc -l < "$file")
    echo "$file: $lines lines"
done

# ✅ 빠름 (한 번에 처리)
wc -l *.txt

# ❌ 느림 (파이프 과다 사용)
cat file.txt | grep "error" | grep "critical" | wc -l

# ✅ 빠름 (grep 한 번에)
grep "error.*critical" file.txt | wc -l

# ✅ 더 빠름 (grep -c)
grep -c "error.*critical" file.txt

병렬 처리

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 순차 처리 (느림)
for file in *.jpg; do
    convert "$file" -resize 800x600 "resized_$file"
done

# 병렬 처리 (빠름)
for file in *.jpg; do
    convert "$file" -resize 800x600 "resized_$file" &
done
wait  # 모든 백그라운드 작업 완료 대기

# GNU parallel 사용 (가장 빠름)
parallel convert {} -resize 800x600 resized_{} ::: *.jpg

17. 실전 도구

fzf (퍼지 파인더)

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 설치
# macOS
brew install fzf

# Ubuntu
sudo apt install fzf

# 사용
# Ctrl+R: 명령어 히스토리 검색
# Ctrl+T: 파일 검색
# Alt+C: 디렉토리 검색

# 스크립트에서 사용
selected_file=$(find . -type f | fzf)
echo "Selected: $selected_file"

ripgrep (빠른 검색)

아래 코드는 bash를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 설치
brew install ripgrep  # macOS
sudo apt install ripgrep  # Ubuntu

# 사용 (grep보다 훨씬 빠름)
rg "error" ./logs
rg -i "warning"  # 대소문자 무시
rg -t js "function"  # JavaScript 파일만
rg "TODO" --stats  # 통계 포함

bat (cat 개선)

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 설치
brew install bat  # macOS
sudo apt install bat  # Ubuntu

# 사용 (문법 하이라이팅)
bat file.js
bat --style=numbers,changes file.js

exa (ls 개선)

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 설치
brew install exa  # macOS
sudo apt install exa  # Ubuntu

# 사용
exa -l  # 자세히
exa -T  # 트리 구조
exa -l --git  # Git 상태 포함

18. CI/CD에서 Shell 활용

GitHub Actions

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Build
      run: |
        npm ci
        npm run build
    
    - name: Deploy
      run: |
        #!/bin/bash
        set -e
        
        echo "Deploying to production..."
        
        # SSH로 서버 접속 및 배포
        ssh user@server << 'EOF'
          cd /var/www/app
          git pull
          npm ci --production
          npm run build
          pm2 restart app
        EOF
        
        echo "Deploy complete!"

GitLab CI

다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

deploy:
  stage: deploy
  script:
    - |
      #!/bin/bash
      set -euxo pipefail
      
      # Docker 이미지 빌드
      docker build -t myapp:$CI_COMMIT_SHA .
      
      # Docker Hub 푸시
      docker push myapp:$CI_COMMIT_SHA
      
      # Kubernetes 배포
      kubectl set image deployment/myapp \
        myapp=myapp:$CI_COMMIT_SHA
  only:
    - main

19. Shell 스크립트 테스트

ShellCheck (정적 분석)

아래 코드는 bash를 사용한 구현 예제입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 설치
brew install shellcheck  # macOS
sudo apt install shellcheck  # Ubuntu

# 사용
shellcheck script.sh

# 출력 예시:
# In script.sh line 5:
# if [ $name = "Alice" ]; then
#      ^-- SC2086: Double quote to prevent globbing

Bats (테스트 프레임워크)

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 설치
npm install -g bats

# test.bats
#!/usr/bin/env bats

@test "addition" {
    result=$(echo $((2 + 2)))
    [ "$result" -eq 4 ]
}

@test "file exists" {
    touch /tmp/test_file
    [ -f /tmp/test_file ]
    rm /tmp/test_file
}

# 실행
bats test.bats

20. 실전 팁

1회성 명령어 vs 스크립트

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 1회성: 명령어 직접 실행
docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm

# 반복 사용: 함수로 만들기
# ~/.bashrc
docker-clean() {
    docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm
}

# 사용
docker-clean

진행 상황 표시

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

files=(*.jpg)
total=${#files[@]}
current=0

for file in "${files[@]}"; do
    current=$((current + 1))
    
    # 진행률 계산
    percent=$((current * 100 / total))
    
    # 진행 바 표시
    printf "\rProcessing: [%-50s] %d%%" \
        $(printf '#%.0s' $(seq 1 $((percent / 2)))) \
        $percent
    
    # 실제 작업
    convert "$file" -resize 800x600 "resized_$file"
done

echo
echo "Complete!"

색상 출력

다음은 bash를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

# 색상 코드
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'  # No Color

# 사용
echo -e "${GREEN}✅ Success${NC}"
echo -e "${RED}❌ Error${NC}"
echo -e "${YELLOW}⚠️  Warning${NC}"
echo -e "${BLUE}ℹ️  Info${NC}"

# 함수로 만들기
success() { echo -e "${GREEN}✅ $1${NC}"; }
error() { echo -e "${RED}❌ $1${NC}"; }
warning() { echo -e "${YELLOW}⚠️  $1${NC}"; }
info() { echo -e "${BLUE}ℹ️  $1${NC}"; }

# 사용
success "Build complete"
error "Build failed"

21. 실전 프로젝트

프로젝트 1: 개발 환경 셋업 스크립트

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

set -e

echo "🚀 개발 환경 셋업 시작..."

# OS 감지
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    OS="linux"
elif [[ "$OSTYPE" == "darwin"* ]]; then
    OS="macos"
else
    echo "Unsupported OS"
    exit 1
fi

# 패키지 매니저 업데이트
echo "📦 패키지 매니저 업데이트..."
if [ "$OS" = "linux" ]; then
    sudo apt update && sudo apt upgrade -y
elif [ "$OS" = "macos" ]; then
    brew update && brew upgrade
fi

# Git 설치
echo "📥 Git 설치..."
if ! command -v git &> /dev/null; then
    if [ "$OS" = "linux" ]; then
        sudo apt install -y git
    elif [ "$OS" = "macos" ]; then
        brew install git
    fi
fi

# Node.js 설치
echo "📥 Node.js 설치..."
if ! command -v node &> /dev/null; then
    if [ "$OS" = "linux" ]; then
        curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
        sudo apt install -y nodejs
    elif [ "$OS" = "macos" ]; then
        brew install node
    fi
fi

# Docker 설치
echo "🐳 Docker 설치..."
if ! command -v docker &> /dev/null; then
    if [ "$OS" = "linux" ]; then
        curl -fsSL https://get.docker.com | sh
        sudo usermod -aG docker $USER
    elif [ "$OS" = "macos" ]; then
        echo "Please install Docker Desktop manually"
    fi
fi

# VSCode 설치
echo "💻 VSCode 설치..."
if ! command -v code &> /dev/null; then
    if [ "$OS" = "linux" ]; then
        sudo snap install code --classic
    elif [ "$OS" = "macos" ]; then
        brew install --cask visual-studio-code
    fi
fi

# Git 설정
echo "⚙️  Git 설정..."
read -p "Git username: " git_username
read -p "Git email: " git_email

git config --global user.name "$git_username"
git config --global user.email "$git_email"
git config --global init.defaultBranch main

# SSH 키 생성
if [ ! -f ~/.ssh/id_ed25519 ]; then
    echo "🔑 SSH 키 생성..."
    ssh-keygen -t ed25519 -C "$git_email" -f ~/.ssh/id_ed25519 -N ""
    echo "SSH 공개 키:"
    cat ~/.ssh/id_ed25519.pub
fi

echo
echo "✅ 개발 환경 셋업 완료!"
echo
echo "설치된 도구:"
echo "- Git: $(git --version)"
echo "- Node.js: $(node --version)"
echo "- npm: $(npm --version)"
echo "- Docker: $(docker --version 2>/dev/null || echo 'Not installed')"
echo "- VSCode: $(code --version 2>/dev/null | head -1 || echo 'Not installed')"

프로젝트 2: 로그 모니터링

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

LOG_FILE="/var/log/nginx/access.log"
ALERT_EMAIL="[email protected]"
ERROR_THRESHOLD=100

# 실시간 로그 모니터링
tail -f "$LOG_FILE" | while read line; do
    # 에러 감지
    if echo "$line" | grep -q "500\|502\|503"; then
        echo "⚠️  Error detected: $line"
        
        # 에러 카운트
        error_count=$(grep -c "50[0-3]" "$LOG_FILE")
        
        # 임계값 초과 시 알림
        if [ "$error_count" -gt "$ERROR_THRESHOLD" ]; then
            echo "🚨 Too many errors! Sending alert..."
            
            # 이메일 알림
            echo "Error count: $error_count" | mail -s "Server Alert" "$ALERT_EMAIL"
            
            # Slack 알림
            curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
                -H 'Content-Type: application/json' \
                -d "{\"text\":\"🚨 Server errors: $error_count\"}"
        fi
    fi
done

프로젝트 3: 서버 배포 스크립트

다음은 bash를 활용한 상세한 구현 코드입니다. 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#!/bin/bash

set -euo pipefail

# 색상
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# 함수
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# 설정
APP_NAME="myapp"
APP_DIR="/var/www/$APP_NAME"
BRANCH="main"
BACKUP_DIR="/backup/$APP_NAME"

# 백업
backup() {
    log_info "Creating backup..."
    
    local backup_file="$BACKUP_DIR/backup_$(date +%Y%m%d_%H%M%S).tar.gz"
    mkdir -p "$BACKUP_DIR"
    
    tar -czf "$backup_file" -C "$APP_DIR" .
    log_info "Backup created: $backup_file"
}

# 배포
deploy() {
    log_info "Starting deployment..."
    
    cd "$APP_DIR"
    
    # 1. 백업
    backup
    
    # 2. Git Pull
    log_info "Pulling latest code..."
    git fetch origin
    git reset --hard origin/$BRANCH
    
    # 3. 의존성 설치
    log_info "Installing dependencies..."
    npm ci --production
    
    # 4. 빌드
    log_info "Building..."
    npm run build
    
    # 5. 데이터베이스 마이그레이션
    log_info "Running migrations..."
    npm run migrate
    
    # 6. 서비스 재시작
    log_info "Restarting service..."
    pm2 restart "$APP_NAME"
    
    # 7. 헬스 체크
    log_info "Health check..."
    sleep 5
    
    local response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/health)
    
    if [ "$response" = "200" ]; then
        log_info "✅ Deployment successful!"
    else
        log_error "❌ Health check failed (HTTP $response)"
        rollback
        exit 1
    fi
}

# 롤백
rollback() {
    log_warn "Rolling back..."
    
    # 최신 백업 찾기
    local latest_backup=$(ls -t "$BACKUP_DIR"/backup_*.tar.gz | head -1)
    
    if [ -z "$latest_backup" ]; then
        log_error "No backup found!"
        exit 1
    fi
    
    log_info "Restoring from: $latest_backup"
    
    cd "$APP_DIR"
    tar -xzf "$latest_backup"
    
    npm ci --production
    pm2 restart "$APP_NAME"
    
    log_info "Rollback complete"
}

# 메인
case "${1:-}" in
    deploy)
        deploy
        ;;
    rollback)
        rollback
        ;;
    backup)
        backup
        ;;
    *)
        echo "Usage: $0 {deploy|rollback|backup}"
        exit 1
        ;;
esac

22. PowerShell 고급 기능

객체 파이프라인

다음은 powershell를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 프로세스 정보 (객체)
Get-Process | 
    Where-Object { $_.CPU -gt 10 } |
    Sort-Object CPU -Descending |
    Select-Object -First 10 Name, CPU, WorkingSet |
    Format-Table -AutoSize

# 파일 크기 합계
Get-ChildItem -Recurse |
    Measure-Object -Property Length -Sum |
    Select-Object @{Name="TotalGB";Expression={[math]::Round($_.Sum / 1GB, 2)}}

# CSV 처리
Import-Csv users.csv |
    Where-Object { $_.Age -gt 18 } |
    Select-Object Name, Email |
    Export-Csv adults.csv -NoTypeInformation

원격 실행

다음은 powershell를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 원격 서버에서 명령어 실행
Invoke-Command -ComputerName Server01 -ScriptBlock {
    Get-Service | Where-Object { $_.Status -eq "Running" }
}

# 여러 서버
$servers = @("Server01", "Server02", "Server03")
Invoke-Command -ComputerName $servers -ScriptBlock {
    Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
}

# 자격 증명
$cred = Get-Credential
Invoke-Command -ComputerName Server01 -Credential $cred -ScriptBlock {
    Restart-Service IIS
}

모듈 및 패키지

아래 코드는 powershell를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 모듈 검색
Find-Module -Name "*Azure*"

# 모듈 설치
Install-Module -Name Az -Scope CurrentUser

# 모듈 가져오기
Import-Module Az

# 설치된 모듈 목록
Get-Module -ListAvailable

# 명령어 검색
Get-Command -Module Az

23. 트러블슈팅

Bash 문제 해결

1) “Permission denied”

# 원인: 실행 권한 없음
# 해결:
chmod +x script.sh

2) “command not found”

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 원인: PATH에 없음
# 해결:
export PATH="/usr/local/bin:$PATH"

# 또는 전체 경로 사용
/usr/local/bin/mycommand

3) “No such file or directory”

아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 원인: 공백 처리 안됨
# ❌ 잘못된 코드
file=my file.txt
cat $file  # cat이 "my"와 "file.txt"를 별도 파일로 인식

# ✅ 올바른 코드
file="my file.txt"
cat "$file"  # 인용 필수!

PowerShell 문제 해결

1) “실행 정책” 에러

아래 코드는 powershell를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 원인: 스크립트 실행 정책
# 해결:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# 확인
Get-ExecutionPolicy

2) “명령어를 찾을 수 없습니다”

아래 코드는 powershell를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# 원인: 모듈 미설치
# 해결:
Install-Module -Name ModuleName

# 또는 PATH 추가
$env:PATH += ";C:\MyTools"

FAQ

Q1. Bash와 Zsh 중 무엇을 쓰나?

서버 스크립트·CI는 Bash가 기본값이 되는 경우가 많다. 로컬 터미널에서 자동 완성·플러그인을 쓰고 싶으면 Zsh로 가는 사람이 많다. macOS는 기본이 Zsh다.

Q2. PowerShell을 Linux에서도 쓰나?

PowerShell Core(pwsh)는 크로스 플랫폼이다. 다만 Linux 서버·문서·예제는 여전히 Bash 쪽이 압도적으로 많다.

Q3. Shell과 Python은 어떻게 나누나?

짧은 파이프라인·배포 스크립트·크론은 셸이 가볍다. 데이터 가공·복잡한 분기·라이브러리가 많으면 Python이 나을 때가 많다.

Q4. 무엇부터 익혀야 하나?

Linux를 쓸 거면 Bash는 피하기 어렵다. 그다음 로컬 환경에 Zsh를 얹거나, Windows 관리면 PowerShell을 병행하면 된다.


요약

핵심 정리

Bash:

  • Linux/macOS 기본 Shell
  • 스크립트 작성에 최적
  • 높은 호환성

Zsh:

  • Bash 호환 + 강력한 기능
  • 자동 완성, 플러그인
  • 대화형 사용에 최적

PowerShell:

  • Windows 현대적 Shell
  • 객체 기반 파이프라인
  • .NET 통합

선택 가이드:

  • Linux 서버 → Bash
  • 개발 환경 → Zsh
  • Windows 관리 → PowerShell
  • CI/CD → Bash (호환성)

필수 명령어

다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# 파일
ls, cd, pwd, cp, mv, rm, mkdir, touch, cat

# 검색
find, grep, awk, sed

# 프로세스
ps, top, kill, jobs, bg, fg

# 네트워크
curl, wget, netstat, ss, ping

# 시스템
df, du, free, uname, uptime

# 압축
tar, gzip, zip, unzip

학습 로드맵

기본 명령·파이프·리다이렉션을 먼저 손에 익히고, 변수·조건·함수로 스크립트를 짜 본다. 그다음 배포·로그·헬스체크처럼 실제로 돌아가는 걸 하나씩 붙이면 된다. fzf·ripgrep 같은 도구는 반복 작업이 느껴질 때 넣어도 늦지 않다.

다음 글 추천


키워드: Shell, Bash, Zsh, PowerShell, Terminal, Linux, Script, , 터미널, 자동화, CLI

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3