メインコンテンツへスキップ
レッスン 8 / 8推定時間: 35

実践総合演習

これまで学んだファイル操作技術を統合して、実際の業務で遭遇するような複雑な課題に挑戦します

このレッスンの学習目標

  • 複数のファイル操作技術を組み合わせて使える
  • 実際の業務に即した問題を解決できる
  • 効率的で保守可能なスクリプトを作成できる
  • ファイル操作のベストプラクティスを実践できる

はじめに

このレッスンでは、これまで学んだファイル操作技術を統合して、実際の業務で遭遇するような複雑な課題に取り組みます。各演習では複数の解法があり、効率性、保守性、拡張性を考慮した最適解を目指します。

演習1: 多言語プロジェクトの整理システム

大規模な多言語開発プロジェクトのファイルを自動整理するシステムを構築します。

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log

要件

  1. ファイルを言語/用途別にディレクトリに整理
  2. テストファイルは特別なディレクトリに配置
  3. 設定ファイルとドキュメントをそれぞれ専用ディレクトリに
  4. 重複ファイルがある場合は警告を出力
  5. 実行前にプレビュー機能を提供

目標構造

organized_project/
├── code/
│   ├── python/
│   ├── javascript/
│   ├── java/
│   ├── go/
│   └── rust/
├── tests/
├── configs/
├── docs/
├── assets/
│   └── images/
└── scripts/

考慮ポイント:

  • ファイル拡張子による自動分類
  • シンボリックリンクの処理
  • ログ出力と進捗表示
  • ロールバック機能

解答例:

#!/bin/bash
# project_organizer.sh

set -euo pipefail

PREVIEW_MODE=false
VERBOSE=false
SOURCE_DIR="."
TARGET_DIR="organized_project"
LOG_FILE="organize.log"

# 関数定義
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

create_directory_structure() {
    local dirs=(
        "code/python"
        "code/javascript"
        "code/java"
        "code/go"
        "code/rust"
        "tests"
        "configs"
        "docs"
        "assets/images"
        "scripts"
    )
    
    for dir in "${dirs[@]}"; do
        mkdir -p "$TARGET_DIR/$dir"
        log "Created directory: $TARGET_DIR/$dir"
    done
}

classify_file() {
    local file="$1"
    local filename=$(basename "$file")
    local extension="${filename##*.}"
    
    # テストファイルの判定
    if [[ "$filename" =~ ^test_ ]] || [[ "$filename" =~ _test\. ]] || [[ "$filename" =~ \.test\. ]]; then
        echo "tests"
        return
    fi
    
    # 拡張子による分類
    case "$extension" in
        py) echo "code/python" ;;
        js) echo "code/javascript" ;;
        java) echo "code/java" ;;
        go) echo "code/go" ;;
        rs) echo "code/rust" ;;
        css|scss|sass) echo "assets/styles" ;;
        jpg|png|svg|gif) echo "assets/images" ;;
        md|txt|pdf) echo "docs" ;;
        json|yaml|toml|ini) echo "configs" ;;
        sh|bat|ps1) echo "scripts" ;;
        *) echo "misc" ;;
    esac
}

organize_files() {
    local moved_count=0
    local skipped_count=0
    
    while IFS= read -r -d '' file; do
        if [[ -d "$file" ]]; then
            continue
        fi
        
        local target_dir=$(classify_file "$file")
        local filename=$(basename "$file")
        local target_path="$TARGET_DIR/$target_dir/$filename"
        
        # 重複チェック
        if [[ -f "$target_path" ]]; then
            if cmp -s "$file" "$target_path"; then
                log "SKIP: Identical file exists: $filename"
                ((skipped_count++))
                continue
            else
                log "WARNING: Different file with same name exists: $filename"
                target_path="${target_path}.$(date +%s)"
            fi
        fi
        
        if [[ "$PREVIEW_MODE" == "true" ]]; then
            echo "PREVIEW: $file -> $target_path"
        else
            mkdir -p "$(dirname "$target_path")"
            cp "$file" "$target_path"
            log "MOVED: $file -> $target_path"
            ((moved_count++))
        fi
    done < <(find "$SOURCE_DIR" -maxdepth 1 -type f -print0)
    
    if [[ "$PREVIEW_MODE" == "false" ]]; then
        log "Organization complete. Moved: $moved_count, Skipped: $skipped_count"
    fi
}

# メイン実行
main() {
    log "Starting project organization..."
    
    if [[ "$PREVIEW_MODE" == "true" ]]; then
        echo "=== PREVIEW MODE ==="
        organize_files
        echo "=== END PREVIEW ==="
        echo "Run without --preview to execute"
    else
        create_directory_structure
        organize_files
        
        # 統計情報
        echo
        echo "=== Organization Summary ==="
        find "$TARGET_DIR" -type f | wc -l | sed 's/^/Total files: /'
        du -sh "$TARGET_DIR" | awk '{print "Total size: " $1}'
    fi
}

# オプション解析
while [[ $# -gt 0 ]]; do
    case $1 in
        --preview)
            PREVIEW_MODE=true
            shift
            ;;
        -v|--verbose)
            VERBOSE=true
            shift
            ;;
        *)
            echo "Unknown option: $1"
            exit 1
            ;;
    esac
done

main

演習2: ログ解析と集計システム

Webサーバーのアクセスログを解析し、統計情報を抽出するシステムを作成します。

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log

要件

  1. アクセス統計の生成

    • 時間別アクセス数
    • ステータスコード別集計
    • IPアドレス別アクセス回数
    • 最もアクセスの多いエンドポイント
  2. エラー解析

    • 4xx/5xxエラーの詳細
    • エラー率の計算
    • 異常なアクセスパターンの検出
  3. レポート生成

    • HTML形式での出力
    • CSV形式での統計データ出力
    • アラート機能

解答例:

#!/bin/bash
# log_analyzer.sh

LOG_FILE="access.log"
REPORT_DIR="reports"
DATE=$(date +%Y%m%d_%H%M%S)
REPORT_FILE="$REPORT_DIR/report_$DATE"

# ディレクトリ作成
mkdir -p "$REPORT_DIR"

analyze_access_patterns() {
    echo "=== Access Analysis Report ===" > "$REPORT_FILE.txt"
    echo "Generated: $(date)" >> "$REPORT_FILE.txt"
    echo >> "$REPORT_FILE.txt"
    
    # 基本統計
    local total_requests=$(wc -l < "$LOG_FILE")
    echo "Total Requests: $total_requests" >> "$REPORT_FILE.txt"
    echo >> "$REPORT_FILE.txt"
    
    # 時間別アクセス
    echo "=== Hourly Access Pattern ===" >> "$REPORT_FILE.txt"
    awk '{gsub(/\[|\]/, "", $4); split($4, dt, ":"); print dt[2]}' "$LOG_FILE" | \
    sort | uniq -c | sort -nr >> "$REPORT_FILE.txt"
    echo >> "$REPORT_FILE.txt"
    
    # ステータスコード別
    echo "=== Status Code Distribution ===" >> "$REPORT_FILE.txt"
    awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -nr >> "$REPORT_FILE.txt"
    echo >> "$REPORT_FILE.txt"
    
    # IP別アクセス
    echo "=== Top 10 IP Addresses ===" >> "$REPORT_FILE.txt"
    awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10 >> "$REPORT_FILE.txt"
    echo >> "$REPORT_FILE.txt"
    
    # エンドポイント別
    echo "=== Top 10 Endpoints ===" >> "$REPORT_FILE.txt"
    awk '{gsub(/\"/, "", $7); print $7}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10 >> "$REPORT_FILE.txt"
}

generate_error_analysis() {
    echo "=== Error Analysis ===" >> "$REPORT_FILE.txt"
    
    # 4xxエラー
    echo "Client Errors (4xx):" >> "$REPORT_FILE.txt"
    awk '$9 ~ /^4/ {print $1, $7, $9}' "$LOG_FILE" >> "$REPORT_FILE.txt"
    echo >> "$REPORT_FILE.txt"
    
    # 5xxエラー
    echo "Server Errors (5xx):" >> "$REPORT_FILE.txt"
    awk '$9 ~ /^5/ {print $1, $7, $9}' "$LOG_FILE" >> "$REPORT_FILE.txt"
    echo >> "$REPORT_FILE.txt"
    
    # エラー率計算
    local total=$(wc -l < "$LOG_FILE")
    local errors=$(awk '$9 !~ /^[23]/' "$LOG_FILE" | wc -l)
    local error_rate=$(awk "BEGIN {printf \"%.2f\", $errors/$total*100}")
    echo "Error Rate: ${error_rate}%" >> "$REPORT_FILE.txt"
}

generate_csv_report() {
    echo "timestamp,ip,method,endpoint,status,bytes,user_agent" > "$REPORT_FILE.csv"
    awk '{
        gsub(/\[|\]/, "", $4);
        gsub(/\"/, "", $6);
        gsub(/\"/, "", $7);
        gsub(/\"/, "", $12);
        print $4 "," $1 "," $6 "," $7 "," $9 "," $10 "," $12
    }' "$LOG_FILE" >> "$REPORT_FILE.csv"
}

generate_html_report() {
    cat > "$REPORT_FILE.html" << 'HTML_TEMPLATE'
<!DOCTYPE html>
<html>
<head>
    <title>Access Log Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .metric { background: #f5f5f5; padding: 10px; margin: 10px 0; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .error { color: red; }
        .warning { color: orange; }
    </style>
</head>
<body>
    <h1>Access Log Analysis Report</h1>
    <div class="metric">
        <strong>Generated:</strong> REPORT_DATE<br>
        <strong>Total Requests:</strong> TOTAL_REQUESTS<br>
        <strong>Error Rate:</strong> ERROR_RATE
    </div>
HTML_TEMPLATE

    # プレースホルダーを実際の値で置換
    local total_requests=$(wc -l < "$LOG_FILE")
    local errors=$(awk '$9 !~ /^[23]/' "$LOG_FILE" | wc -l)
    local error_rate=$(awk "BEGIN {printf \"%.2f\", $errors/$total_requests*100}")
    
    sed -i "s/REPORT_DATE/$(date)/g" "$REPORT_FILE.html"
    sed -i "s/TOTAL_REQUESTS/$total_requests/g" "$REPORT_FILE.html"
    sed -i "s/ERROR_RATE/${error_rate}%/g" "$REPORT_FILE.html"
    
    echo "</body></html>" >> "$REPORT_FILE.html"
}

check_alerts() {
    local errors=$(awk '$9 !~ /^[23]/' "$LOG_FILE" | wc -l)
    local total=$(wc -l < "$LOG_FILE")
    local error_rate=$(awk "BEGIN {printf \"%.0f\", $errors/$total*100}")
    
    if [[ $error_rate -gt 20 ]]; then
        echo "ALERT: High error rate detected: ${error_rate}%" | tee "$REPORT_DIR/alert_$DATE.txt"
    fi
    
    # 異常なアクセス頻度をチェック
    awk '{print $1}' "$LOG_FILE" | sort | uniq -c | while read count ip; do
        if [[ $count -gt 100 ]]; then
            echo "ALERT: High access frequency from IP $ip: $count requests" | tee -a "$REPORT_DIR/alert_$DATE.txt"
        fi
    done
}

# メイン実行
main() {
    echo "Starting log analysis..."
    
    analyze_access_patterns
    generate_error_analysis
    generate_csv_report
    generate_html_report
    check_alerts
    
    echo "Analysis complete. Reports generated:"
    echo "  - Text: $REPORT_FILE.txt"
    echo "  - CSV: $REPORT_FILE.csv"
    echo "  - HTML: $REPORT_FILE.html"
    
    if [[ -f "$REPORT_DIR/alert_$DATE.txt" ]]; then
        echo "  - Alerts: $REPORT_DIR/alert_$DATE.txt"
    fi
}

main

演習3: バックアップとリストア システム

増分バックアップ、世代管理、自動復旧機能を持つ包括的なバックアップシステムを構築します。

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log

要件

  1. 増分バックアップシステム

    • 初回フルバックアップ
    • 差分バックアップ
    • ハードリンクによる容量節約
  2. 世代管理

    • 日次、週次、月次バックアップ
    • 古い世代の自動削除
    • 世代間の整合性チェック
  3. 復旧機能

    • 特定時点への復旧
    • 個別ファイルの復旧
    • 破損検証
  4. 監視とログ

    • 実行ログ
    • 成功/失敗通知
    • 容量使用量監視

解答例:

#!/bin/bash
# advanced_backup.sh

set -euo pipefail

# 設定
CONFIG_FILE="${1:-backup.conf}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="/var/log/backup"
LOCK_FILE="/var/run/backup.lock"

# デフォルト設定
SOURCE_DIR=""
BACKUP_ROOT=""
RETENTION_DAYS=7
RETENTION_WEEKS=4
RETENTION_MONTHS=6
COMPRESSION=true
CHECKSUM_VERIFY=true
EMAIL_ALERTS=""

# 設定ファイルの読み込み
if [[ -f "$CONFIG_FILE" ]]; then
    source "$CONFIG_FILE"
fi

# ログ関数
log() {
    local level="$1"
    shift
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" | tee -a "$LOG_DIR/backup.log"
}

# ロック管理
acquire_lock() {
    if [[ -f "$LOCK_FILE" ]]; then
        local pid=$(cat "$LOCK_FILE")
        if kill -0 "$pid" 2>/dev/null; then
            log "ERROR" "Another backup process is running (PID: $pid)"
            exit 1
        else
            log "WARN" "Stale lock file found, removing..."
            rm -f "$LOCK_FILE"
        fi
    fi
    echo $$ > "$LOCK_FILE"
}

release_lock() {
    rm -f "$LOCK_FILE"
}

# クリーンアップ
cleanup() {
    release_lock
    if [[ ${1:-0} -ne 0 ]]; then
        log "ERROR" "Backup failed with exit code $1"
        send_alert "BACKUP FAILED" "Backup process failed. Check logs for details."
    fi
}

trap 'cleanup $?' EXIT

# アラート送信
send_alert() {
    local subject="$1"
    local message="$2"
    
    if [[ -n "$EMAIL_ALERTS" ]]; then
        echo "$message" | mail -s "$subject" "$EMAIL_ALERTS"
    fi
    log "ALERT" "$subject: $message"
}

# バックアップタイプの決定
determine_backup_type() {
    local day_of_week=$(date +%u)
    local day_of_month=$(date +%d)
    
    if [[ "$day_of_month" == "01" ]]; then
        echo "monthly"
    elif [[ "$day_of_week" == "7" ]]; then
        echo "weekly"
    else
        echo "daily"
    fi
}

# フルバックアップ
full_backup() {
    local timestamp="$1"
    local backup_dir="$BACKUP_ROOT/full/$timestamp"
    
    log "INFO" "Starting full backup to $backup_dir"
    
    mkdir -p "$backup_dir"
    
    local rsync_opts="-av --stats"
    [[ "$COMPRESSION" == true ]] && rsync_opts="$rsync_opts --compress"
    [[ "$CHECKSUM_VERIFY" == true ]] && rsync_opts="$rsync_opts --checksum"
    
    if rsync $rsync_opts "$SOURCE_DIR/" "$backup_dir/" > "$LOG_DIR/rsync_full_$timestamp.log" 2>&1; then
        log "INFO" "Full backup completed successfully"
        echo "$timestamp" > "$BACKUP_ROOT/latest_full"
    else
        log "ERROR" "Full backup failed"
        return 1
    fi
}

# 増分バックアップ
incremental_backup() {
    local timestamp="$1"
    local backup_type="$2"
    local backup_dir="$BACKUP_ROOT/$backup_type/$timestamp"
    
    local latest_full=$(cat "$BACKUP_ROOT/latest_full" 2>/dev/null || echo "")
    if [[ -z "$latest_full" ]]; then
        log "WARN" "No full backup found, performing full backup instead"
        full_backup "$timestamp"
        return $?
    fi
    
    log "INFO" "Starting incremental backup to $backup_dir"
    
    mkdir -p "$backup_dir"
    
    local link_dest="--link-dest=$BACKUP_ROOT/full/$latest_full"
    
    # 最新の増分バックアップも参照
    local latest_incremental
    latest_incremental=$(ls -1t "$BACKUP_ROOT/$backup_type"/ 2>/dev/null | head -1 || echo "")
    if [[ -n "$latest_incremental" ]]; then
        link_dest="$link_dest --link-dest=$BACKUP_ROOT/$backup_type/$latest_incremental"
    fi
    
    local rsync_opts="-av --stats $link_dest"
    [[ "$COMPRESSION" == true ]] && rsync_opts="$rsync_opts --compress"
    
    if rsync $rsync_opts "$SOURCE_DIR/" "$backup_dir/" > "$LOG_DIR/rsync_${backup_type}_$timestamp.log" 2>&1; then
        log "INFO" "Incremental backup completed successfully"
    else
        log "ERROR" "Incremental backup failed"
        return 1
    fi
}

# 古いバックアップの削除
cleanup_old_backups() {
    log "INFO" "Cleaning up old backups"
    
    # 日次バックアップ
    find "$BACKUP_ROOT/daily" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \; 2>/dev/null || true
    
    # 週次バックアップ
    find "$BACKUP_ROOT/weekly" -maxdepth 1 -type d -mtime +$((RETENTION_WEEKS * 7)) -exec rm -rf {} \; 2>/dev/null || true
    
    # 月次バックアップ
    find "$BACKUP_ROOT/monthly" -maxdepth 1 -type d -mtime +$((RETENTION_MONTHS * 30)) -exec rm -rf {} \; 2>/dev/null || true
}

# バックアップの検証
verify_backup() {
    local backup_dir="$1"
    log "INFO" "Verifying backup: $backup_dir"
    
    # ファイル数の比較
    local source_count=$(find "$SOURCE_DIR" -type f | wc -l)
    local backup_count=$(find "$backup_dir" -type f | wc -l)
    
    if [[ "$source_count" -ne "$backup_count" ]]; then
        log "WARN" "File count mismatch: source=$source_count, backup=$backup_count"
    fi
    
    # サンプリング検証
    find "$SOURCE_DIR" -type f | shuf | head -10 | while read -r file; do
        local rel_path="${file#$SOURCE_DIR/}"
        local backup_file="$backup_dir/$rel_path"
        
        if [[ ! -f "$backup_file" ]]; then
            log "ERROR" "Missing file in backup: $rel_path"
        elif ! cmp -s "$file" "$backup_file"; then
            log "ERROR" "File content mismatch: $rel_path"
        fi
    done
}

# 使用量レポート
generate_usage_report() {
    log "INFO" "Generating usage report"
    
    local report_file="$LOG_DIR/usage_report_$(date +%Y%m%d).txt"
    
    {
        echo "=== Backup Usage Report ==="
        echo "Generated: $(date)"
        echo
        echo "Source Directory: $SOURCE_DIR"
        echo "Backup Root: $BACKUP_ROOT"
        echo
        echo "=== Disk Usage ==="
        du -sh "$BACKUP_ROOT"/* 2>/dev/null || echo "No backups found"
        echo
        echo "=== Backup Count ==="
        find "$BACKUP_ROOT" -maxdepth 2 -type d | grep -E '[0-9]{8}_[0-9]{6}$' | wc -l | sed 's/^/Total backups: /'
        echo
        echo "=== Recent Backups ==="
        find "$BACKUP_ROOT" -maxdepth 2 -type d -name '*_*' | sort -t/ -k3 -r | head -10
    } > "$report_file"
    
    cat "$report_file"
}

# メイン実行
main() {
    local command="${1:-backup}"
    
    case "$command" in
        backup)
            mkdir -p "$LOG_DIR" "$BACKUP_ROOT"/{full,daily,weekly,monthly}
            acquire_lock
            
            local timestamp=$(date +%Y%m%d_%H%M%S)
            local backup_type=$(determine_backup_type)
            
            log "INFO" "Starting $backup_type backup"
            
            if [[ "$backup_type" == "monthly" ]] && [[ ! -d "$BACKUP_ROOT/full" || -z "$(ls -A "$BACKUP_ROOT/full" 2>/dev/null)" ]]; then
                full_backup "$timestamp"
            else
                incremental_backup "$timestamp" "$backup_type"
            fi
            
            verify_backup "$BACKUP_ROOT/$backup_type/$timestamp"
            cleanup_old_backups
            generate_usage_report
            
            log "INFO" "Backup process completed"
            ;;
        restore)
            echo "Restore functionality - implement based on specific needs"
            ;;
        list)
            find "$BACKUP_ROOT" -maxdepth 2 -type d -name '*_*' | sort
            ;;
        verify)
            echo "Verification functionality - implement based on specific needs"
            ;;
        *)
            echo "Usage: $0 [backup|restore|list|verify]"
            exit 1
            ;;
    esac
}

# 設定ファイルの例作成
create_config_template() {
    cat > backup.conf.template << 'EOF'
# Backup Configuration
SOURCE_DIR="/home/user/documents"
BACKUP_ROOT="/backup/storage"

# Retention settings
RETENTION_DAYS=7
RETENTION_WEEKS=4
RETENTION_MONTHS=6

# Options
COMPRESSION=true
CHECKSUM_VERIFY=true

# Alerts
EMAIL_ALERTS="admin@example.com"
EOF
}

# メイン実行
main "$@"

演習4: ファイルシステム監視とレポート

ファイルシステムの変更を監視し、定期的にレポートを生成するシステムを作成します。

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log

要件

  1. リアルタイム監視

    • ファイルの作成、変更、削除を検出
    • 大きなファイルの監視
    • 権限変更の検出
  2. 定期レポート

    • 日次/週次/月次のサマリー
    • 容量の変化トレンド
    • アクティビティの統計
  3. アラート機能

    • 異常なアクティビティの検出
    • 容量の急激な増加
    • 重要ファイルの変更

解答例(監視システムの基本構造):

#!/bin/bash
# filesystem_monitor.sh

WATCH_DIRS=("/home/user/documents" "/var/www")
REPORT_DIR="/var/log/filesystem-monitor"
ALERT_EMAIL="admin@example.com"
ALERT_THRESHOLD_SIZE=$((1024 * 1024 * 100))  # 100MB

setup_monitoring() {
    mkdir -p "$REPORT_DIR"
    
    # inotifywait を使った監視
    for dir in "${WATCH_DIRS[@]}"; do
        (
            inotifywait -m -r -e modify,create,delete,move,attrib "$dir" |
            while read -r path event file; do
                log_event "$path" "$event" "$file"
                check_alerts "$path/$file" "$event"
            done
        ) &
    done
}

log_event() {
    local path="$1"
    local event="$2"
    local file="$3"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    echo "$timestamp|$event|$path/$file" >> "$REPORT_DIR/activity.log"
}

check_alerts() {
    local full_path="$1"
    local event="$2"
    
    # ファイルサイズチェック
    if [[ "$event" == "CREATE" || "$event" == "MODIFY" ]] && [[ -f "$full_path" ]]; then
        local size=$(stat -c%s "$full_path" 2>/dev/null || echo 0)
        if [[ $size -gt $ALERT_THRESHOLD_SIZE ]]; then
            send_alert "Large file detected" "File: $full_path, Size: $(numfmt --to=iec $size)"
        fi
    fi
}

generate_daily_report() {
    local date=$(date +%Y-%m-%d)
    local report_file="$REPORT_DIR/daily_report_$date.txt"
    
    {
        echo "=== Daily Filesystem Activity Report ==="
        echo "Date: $date"
        echo
        
        echo "=== Activity Summary ==="
        grep "^$date" "$REPORT_DIR/activity.log" | cut -d'|' -f2 | sort | uniq -c
        
        echo
        echo "=== Large Files Created ==="
        find "${WATCH_DIRS[@]}" -type f -newerct "$date" -size +10M -ls
        
        echo
        echo "=== Disk Usage Changes ==="
        for dir in "${WATCH_DIRS[@]}"; do
            echo "$dir: $(du -sh "$dir" 2>/dev/null | cut -f1)"
        done
    } > "$report_file"
    
    echo "$report_file"
}

main() {
    case "${1:-monitor}" in
        monitor)
            echo "Starting filesystem monitoring..."
            setup_monitoring
            wait  # Keep script running
            ;;
        report)
            generate_daily_report
            ;;
        *)
            echo "Usage: $0 [monitor|report]"
            ;;
    esac
}

main "$@"

総合課題: エンタープライズファイル管理システム

すべての学習内容を統合した、企業環境での実用的なファイル管理システムを構築してください。

システム要件

  1. 自動分類とタグ付け

    • ファイルタイプ別の自動振り分け
    • メタデータによるタグ付け
    • 重複ファイルの検出と統合
  2. バックアップとアーカイブ

    • 自動増分バックアップ
    • 長期保存用アーカイブ
    • クラウドストレージ連携
  3. セキュリティとコンプライアンス

    • アクセス権限の自動設定
    • 監査ログの生成
    • 機密情報の自動検出
  4. レポートと監視

    • 使用量レポート
    • アクティビティ監視
    • アラート機能
  5. ユーザーインターフェース

    • コマンドライン操作
    • 設定ファイルによる管理
    • Web インターフェース(オプション)

この総合課題では、以下の技術を組み合わせてください:

  • 高度なファイル操作コマンド
  • シェルスクリプティング
  • システム監視技術
  • セキュリティベストプラクティス
  • パフォーマンス最適化

コース完了

おめでとうございます!ファイル操作マスターコースを完了しました。

習得したスキル

  • 高度なファイル管理テクニック
  • 圧縮とアーカイブの活用
  • リンクシステムの理解
  • システム監視と容量管理
  • ファイル属性とセキュリティ
  • 高度な同期技術
  • 効率的な検索手法
  • 実践的な問題解決能力

次のステップ

  1. 実際の環境での練習

    • 本番環境での段階的導入
    • 既存システムとの統合
    • パフォーマンスの監視
  2. さらなる学習

    • システム管理の高度なトピック
    • クラウドストレージ連携
    • DevOps での活用
  3. コミュニティへの貢献

    • オープンソースプロジェクトへの参加
    • 知識の共有とメンタリング

🎉 素晴らしい成果です!学んだ技術を組み合わせることで、複雑なファイル管理課題も効率的に解決できるようになりました。継続的な実践と学習で、さらなるスキル向上を目指しましょう!

さらに学習を続けるには

素晴らしい学習ペースです!次のレッスンに進むには、無料会員登録をお願いします。無料会員では各コース3レッスンまで学習できます。

無料で続きを学ぶ

各コース3レッスンまで学習可能

学習進捗の自動保存

コース修了証明書の発行