第4章:シェルとコマンド - 対話的管理の基礎
4.1 はじめに:なぜ黒い画面と向き合うのか
「なぜ2024年にもなって、マウスではなくキーボードで操作するの?」
これは、Linux初心者が必ず抱く疑問です。スマートフォンやタブレットが当たり前の時代に、文字だけの黒い画面(ターミナル)で作業することは、時代遅れに見えるかもしれません。
しかし、プロのエンジニアがCUI(Character User Interface)を選ぶのには、明確な理由があります。それは「効率」「正確性」「自動化」の3つです。
4.2 なぜGUIではなくCUIが主流なのか
実例で理解する:1000個のファイル名を変更する
あなたは、デジタルカメラで撮影した1000枚の写真ファイルの名前を変更する必要があるとします。
GUIでの作業
- ファイルを一つクリック
- 右クリックして「名前の変更」
- 新しい名前を入力
- Enterキーを押す
- 次のファイルへ…(これを1000回繰り返す)
所要時間:1ファイル10秒として、約3時間
CUIでの作業
# IMG_*.jpg を photo_001.jpg, photo_002.jpg... に変更
counter=1
for file in IMG_*.jpg; do
mv "$file" "photo_$(printf %03d $counter).jpg"
((counter++))
done
所要時間:コマンド入力30秒 + 実行1秒 = 31秒
CUIの本質的な優位性
1. 再現性 - 同じ作業を確実に繰り返せる
# 作業手順をスクリプトとして保存
cat > rename_photos.sh << 'EOF'
#!/bin/bash
counter=1
for file in IMG_*.jpg; do
mv "$file" "photo_$(printf %03d $counter).jpg"
((counter++))
done
EOF
# 1年後、同じ作業が必要になったら
bash rename_photos.sh
GUIでは「あのとき、どうやったっけ?」となりますが、CUIなら完全に再現できます。
2. 自動化 - 人間の介入なしで実行
# 毎日午前3時に自動的にバックアップ
crontab -e
# 以下を追加
0 3 * * * /home/user/backup_script.sh
サーバー管理において、24時間365日人間が画面を見ているわけにはいきません。
3. リモート操作 - どこからでも同じように作業
# 東京のオフィスから、大阪のサーバーを操作
ssh osaka-server
# ニューヨークの自宅から、東京のサーバーを操作
ssh tokyo-server
GUIをリモートで操作するには大量のデータ転送が必要ですが、CUIならテキストデータだけで済みます。
実際の現場での使用例
Webサーバーの管理
# アクセスログから攻撃を検出
grep "SELECT.*FROM.*WHERE" /var/log/nginx/access.log | \
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# 攻撃元IPをブロック
for ip in $(上記コマンドの結果); do
iptables -A INPUT -s $ip -j DROP
done
このような緊急対応を、GUIで行うことを想像してみてください。
4.3 シェルとは何か - コマンドの通訳者
シェルの役割
シェルは、人間とカーネルの間に立つ「通訳者」です:
人間:「このディレクトリのファイル一覧を見せて」
↓
シェル:「なるほど、lsコマンドですね」
↓ システムコールに翻訳
カーネル:「了解、ファイル情報を返します」
↓
シェル:「見やすい形式に整形しました」
↓
人間:「ありがとう!」
カーネルの役割をより具体的に理解する
カーネルは「Linuxの核となるソフトウェア」ですが、より具体的には以下の役割を担っています:
1. リソース管理の交通整理役
# CPUの時間を複数のプロセスに公平に配分
プロセスA: Xms実行 → 待機
プロセスB: Xms実行 → 待機
プロセスC: Xms実行 → 待機
プロセスA: Xms実行...(繰り返し)
# 注: 実際のCPUスケジューリングにおける時間スライスの長さ(Xms)は、
# システムやスケジューラ、負荷に応じて異なります。
2. メモリの受付係
# プロセスがメモリを要求すると、カーネルが仲裁
アプリケーション: 「1GBのメモリが欲しい」
カーネル: 「利用可能です。アドレス0x12345000〜を割り当てます」
「(注:このアドレスは例示用であり、実際のアドレスではありません)」
「他のプロセスはここにアクセスできません」
3. ハードウェアとの仲介役
# キーボード入力をどのプログラムに渡すか決定
キーボード: 「'ls'がタイプされました」
カーネル: 「現在アクティブなターミナルプロセス(PID 1234)に送信」
ターミナル: lsコマンドを実行
この仕組みにより、複数のプログラムが喧嘩することなく、一つのコンピュータで同時に動作できるのです。
主要なシェルの種類
# 利用可能なシェルを確認
cat /etc/shells
# /bin/bash - Bourne Again Shell(最も一般的)
# /bin/sh - Bourne Shell(基本的なシェル)
# /bin/zsh - Z Shell(高機能)
# /bin/fish - Friendly Interactive Shell(初心者向け)
本書では、最も普及しているbash
を中心に解説します。
シェルの基本機能
1. コマンドの実行
# 単純なコマンド実行
ls
# オプション付き
ls -la
# 引数付き
ls -la /etc
2. 変数の管理
# 変数の設定
NAME="Linux"
echo "Hello, $NAME!"
# 環境変数
export PATH=$PATH:/usr/local/bin
echo $PATH
3. 制御構造
# 条件分岐
if [ -f /etc/passwd ]; then
echo "パスワードファイルが存在します"
fi
# ループ
for i in {1..5}; do
echo "Count: $i"
done
4.4 パイプラインが実現する「部品の組み合わせ」
パイプの概念
パイプ( | )は、あるコマンドの出力を別のコマンドの入力につなぐ「配管」です: |
コマンド1の出力 | コマンド2の入力 | コマンド3の入力
実例:アクセスログの解析
# 基本:ログファイルを見る
cat access.log
# ステップ1:今日の分だけ抽出
cat access.log | grep "2024-03-15"
# ステップ2:エラー(4xx, 5xx)だけ抽出
cat access.log | grep "2024-03-15" | grep -E "(4[0-9]{2}|5[0-9]{2})"
# ステップ3:IPアドレスだけ取り出す
cat access.log | grep "2024-03-15" | grep -E "(4[0-9]{2}|5[0-9]{2})" | cut -d' ' -f1
# ステップ4:集計してソート
cat access.log | grep "2024-03-15" | grep -E "(4[0-9]{2}|5[0-9]{2})" | \
cut -d' ' -f1 | sort | uniq -c | sort -rn
# 結果:エラーを多く発生させているIPアドレスのランキング
パイプラインの設計思想
1. 各コマンドは単機能
grep
:パターンマッチングcut
:フィールド抽出sort
:並び替えuniq
:重複除去wc
:カウント
2. 入出力の標準化
すべてのコマンドは:
- 標準入力から読む
- 標準出力に書く
- エラーは標準エラー出力へ
この統一により、どんなコマンドも自由に組み合わせられます。
強力なテキスト処理コマンド
grep - パターン検索
# 基本的な検索
grep "error" logfile.txt
# 大文字小文字を無視
grep -i "error" logfile.txt
# 正規表現を使用
grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" logfile.txt
# マッチしない行を表示
grep -v "success" logfile.txt
# マッチした行数をカウント
grep -c "error" logfile.txt
sed - ストリームエディタ
# 文字列の置換
echo "Hello World" | sed 's/World/Linux/'
# ファイル内の全置換
sed -i 's/old/new/g' file.txt
# 特定の行を削除
sed '5d' file.txt # 5行目を削除
# パターンにマッチする行を削除
sed '/^#/d' config.file # コメント行を削除
awk - パターン処理言語
# 特定のフィールドを抽出
ps aux | awk '{print $1, $11}' # ユーザー名とコマンド名
# 条件付き処理
df -h | awk '$5 > 80 {print $6 " is " $5 " full"}' # 使用率80%以上
# 集計
ls -l | awk '{sum += $5} END {print "Total:", sum}' # ファイルサイズの合計
# 複雑な処理
awk '{
count[$1]++
} END {
for (ip in count) {
print ip, count[ip]
}
}' access.log # IPアドレスごとのアクセス数
4.5 自動化・再現性・監査証跡の確保
なぜ自動化が重要なのか
人的ミスの排除
# 手作業の場合
1. サーバーAにログイン
2. 設定ファイルを編集
3. サービスを再起動
4. サーバーBにログイン
5. 設定ファイルを編集(あれ、さっきと同じ内容だっけ?)
6. サービスを再起動(あれ、コマンド何だっけ?)
# 自動化スクリプト
for server in serverA serverB serverC; do
scp nginx.conf $server:/etc/nginx/
ssh $server "nginx -t && systemctl reload nginx"
done
スクリプト化の基本
シェルスクリプトの構造
#!/bin/bash
# daily_backup.sh - 日次バックアップスクリプト
# 設定
BACKUP_DIR="/backup"
SOURCE_DIR="/var/www"
DATE=$(date +%Y%m%d)
LOG_FILE="/var/log/backup.log"
# 関数定義
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
# メイン処理
log_message "バックアップ開始"
# バックアップディレクトリ作成
if [ ! -d "$BACKUP_DIR/$DATE" ]; then
mkdir -p "$BACKUP_DIR/$DATE"
fi
# バックアップ実行
if tar -czf "$BACKUP_DIR/$DATE/www_backup.tar.gz" "$SOURCE_DIR" 2>>$LOG_FILE; then
log_message "バックアップ成功"
# 古いバックアップを削除(7日以上前)
find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} \; 2>/dev/null
log_message "古いバックアップを削除"
else
log_message "エラー: バックアップ失敗"
exit 1
fi
log_message "バックアップ完了"
監査証跡(Audit Trail)の重要性
historyコマンドによる操作履歴
# 実行したコマンドの履歴を見る
history
# 特定のコマンドを検索
history | grep nginx
# タイムスタンプ付きで記録
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
history
scriptコマンドによる完全な記録
# セッション全体を記録
script -a /var/log/admin/session_$(date +%Y%m%d_%H%M%S).log
# 作業実施...
# 記録終了
exit
# 後で確認
cat /var/log/admin/session_*.log
実践的な自動化の例
1. システム監視スクリプト
#!/bin/bash
# monitor.sh - シンプルなシステム監視
# しきい値設定
CPU_THRESHOLD=80
MEM_THRESHOLD=90
DISK_THRESHOLD=85
# CPU使用率チェック
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
echo "警告: CPU使用率が${cpu_usage}%です" | mail -s "CPU Alert" admin@example.com
fi
# メモリ使用率チェック
mem_usage=$(free | grep Mem | awk '{print ($2-$7)/$2 * 100}')
if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
echo "警告: メモリ使用率が${mem_usage}%です" | mail -s "Memory Alert" admin@example.com
fi
# ディスク使用率チェック
df -h | grep -vE '^Filesystem|tmpfs|devtmpfs' | awk '{print $5 " " $6}' | while read usage mount; do
usage_int=${usage%\%}
if [ $usage_int -ge $DISK_THRESHOLD ]; then
echo "警告: $mount のディスク使用率が${usage}です" | mail -s "Disk Alert" admin@example.com
fi
done
2. ログローテーションスクリプト
#!/bin/bash
# log_rotate.sh - カスタムログローテーション
LOG_DIR="/var/log/myapp"
ARCHIVE_DIR="/var/log/myapp/archive"
DAYS_TO_KEEP=30
# アーカイブディレクトリ作成
mkdir -p $ARCHIVE_DIR
# ログファイルをローテート
for logfile in $LOG_DIR/*.log; do
if [ -f "$logfile" ]; then
basename=$(basename "$logfile")
timestamp=$(date +%Y%m%d_%H%M%S)
# 圧縮してアーカイブ
gzip -c "$logfile" > "$ARCHIVE_DIR/${basename%.log}_$timestamp.gz"
# 元のログファイルをクリア
> "$logfile"
fi
done
# 古いアーカイブを削除
find $ARCHIVE_DIR -name "*.gz" -mtime +$DAYS_TO_KEEP -delete
echo "ログローテーション完了: $(date)"
4.6 演習:同じ作業をGUIとCUIで比較
演習1:ファイル検索の比較
タスク:ホームディレクトリ以下で、過去7日間に変更された.txtファイルを探す
GUI方式:
- ファイルマネージャーを開く
- 検索機能を起動
- 検索条件を設定(拡張子、日付)
- 検索実行
- 結果を確認
CUI方式:
find ~ -name "*.txt" -mtime -7
発展:見つかったファイルの合計サイズを計算
find ~ -name "*.txt" -mtime -7 -exec ls -l {} \; | awk '{sum += $5} END {print "Total: " sum " bytes"}'
演習2:大量ファイルの一括処理
タスク:100個のCSVファイルの1行目(ヘッダー)だけを抽出して一つのファイルにまとめる
準備:テスト用のCSVファイルを作成
# テストデータ作成
for i in {1..100}; do
echo "id,name,email,date" > test_$i.csv
echo "$i,User$i,user$i@example.com,2024-03-15" >> test_$i.csv
done
GUI方式:
- 各ファイルを開く
- 1行目をコピー
- 新しいファイルにペースト
- 100回繰り返す…
CUI方式:
# 方法1:headコマンドを使用
for file in test_*.csv; do
head -1 "$file"
done > headers.txt
# 方法2:awkを使用
awk 'FNR==1' test_*.csv > headers.txt
演習3:システム情報の定期収集
タスク:5秒ごとにCPU使用率を記録し、1分後にグラフ化する
# データ収集スクリプト
cat > collect_cpu.sh << 'EOF'
#!/bin/bash
echo "timestamp,cpu_usage" > cpu_data.csv
for i in {1..12}; do
timestamp=$(date +%s)
cpu=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
echo "$timestamp,$cpu" >> cpu_data.csv
sleep 5
done
EOF
# 実行
bash collect_cpu.sh
# 簡易グラフ表示(gnuplotが必要)
gnuplot -e "
set datafile separator ',';
set xlabel 'Time';
set ylabel 'CPU Usage (%)';
plot 'cpu_data.csv' using 1:2 with lines title 'CPU Usage';
pause -1
"
演習4:エラーログの自動監視
タスク:ログファイルを監視し、特定のエラーが出たら通知する
# 監視スクリプト
cat > watch_errors.sh << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/syslog"
ERROR_PATTERN="error|failed|critical"
NOTIFICATION_METHOD="echo" # 実際はmail,slackなど
# 最後に読んだ位置を記録
BOOKMARK_FILE="/tmp/log_bookmark"
if [ ! -f "$BOOKMARK_FILE" ]; then
echo 0 > "$BOOKMARK_FILE"
fi
# 前回の位置から読む
last_position=$(cat "$BOOKMARK_FILE")
current_size=$(stat -c%s "$LOG_FILE")
if [ $current_size -gt $last_position ]; then
# 新しい部分だけを読む
tail -c +$((last_position + 1)) "$LOG_FILE" | grep -iE "$ERROR_PATTERN" | while read line; do
$NOTIFICATION_METHOD "Error detected: $line"
done
# 現在位置を保存
echo $current_size > "$BOOKMARK_FILE"
fi
EOF
# cronで定期実行
crontab -e
# */5 * * * * /path/to/watch_errors.sh
演習5:統合演習 - Webサーバーのアクセス解析ダッシュボード
#!/bin/bash
# web_analytics.sh - リアルタイムWebアクセス解析
analyze_log() {
local log_file="/var/log/nginx/access.log"
echo "=== Web Access Analytics - $(date) ==="
echo
# 総アクセス数
total_requests=$(wc -l < "$log_file")
echo "Total Requests: $total_requests"
echo
# ステータスコード別集計
echo "Status Code Distribution:"
awk '{print $9}' "$log_file" | sort | uniq -c | sort -rn | head -10
echo
# トップ10アクセスページ
echo "Top 10 Pages:"
awk '{print $7}' "$log_file" | sort | uniq -c | sort -rn | head -10
echo
# トップ10アクセス元IP
echo "Top 10 Client IPs:"
awk '{print $1}' "$log_file" | sort | uniq -c | sort -rn | head -10
echo
# 時間帯別アクセス数
echo "Hourly Access Pattern:"
awk '{print substr($4,14,2)}' "$log_file" | sort | uniq -c
echo
# レスポンスサイズの統計
echo "Response Size Statistics:"
awk '{sum+=$10; count++} END {
print "Total bytes: " sum
print "Average bytes: " sum/count
}' "$log_file"
}
# リアルタイム更新
while true; do
clear
analyze_log
echo
echo "Refreshing in 10 seconds... (Press Ctrl+C to stop)"
sleep 10
done
4.7 システムパフォーマンス監視ダッシュボード
リアルタイム監視システムの構築
graph TB
subgraph "データ収集層"
A1["CPU使用率<br/>top, ps, /proc/stat"]
A2["メモリ使用量<br/>free, /proc/meminfo"]
A3[ディスクI/O<br/>iostat, /proc/diskstats]
A4[ネットワーク<br/>ss, /proc/net/dev]
A5["プロセス情報<br/>ps, /proc/*/status"]
A6[ログファイル<br/>tail -f, journalctl]
end
subgraph "データ処理層"
B1["テキスト処理<br/>grep, awk, sed"]
B2["数値計算<br/>bc, expr"]
B3["集計・ソート<br/>sort, uniq, wc"]
B4["時系列データ<br/>watch, while loop"]
end
subgraph "出力・アラート層"
C1["リアルタイム表示<br/>watch, clear"]
C2[ファイル出力<br/>CSV, JSON, LOG]
C3["アラート通知<br/>mail, slack API"]
C4["グラフ化<br/>gnuplot, ASCII chart"]
end
subgraph "自動化層"
D1["cron定期実行"]
D2[systemd service]
D3["シグナル制御"]
D4["プロセス管理"]
end
A1 --> B1
A2 --> B2
A3 --> B3
A4 --> B1
A5 --> B4
A6 --> B1
B1 --> C1
B2 --> C2
B3 --> C3
B4 --> C4
C1 --> D1
C2 --> D2
C3 --> D3
C4 --> D4
style A1 fill:#e1f5fe
style A2 fill:#e1f5fe
style A3 fill:#e1f5fe
style A4 fill:#e1f5fe
style A5 fill:#e1f5fe
style A6 fill:#e1f5fe
style C1 fill:#e8f5e8
style C2 fill:#e8f5e8
style C3 fill:#fff3e0
style C4 fill:#f3e5f5
統合監視スクリプト実装例
#!/bin/bash
# comprehensive_monitor.sh - 包括的システム監視
# 設定
ALERT_CPU=80
ALERT_MEM=90
ALERT_DISK=85
LOG_FILE="/var/log/system_monitor.log"
# メトリクス収集関数
collect_metrics() {
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
# CPU使用率(vmstatでより信頼性の高い取得)
local cpu_usage=$(vmstat 1 2 | tail -1 | awk '{print 100-$15}')
# メモリ使用率
local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
local mem_avail=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
local mem_usage=$(echo "scale=1; (($mem_total - $mem_avail) * 100) / $mem_total" | bc)
# ディスク使用率
local disk_usage=$(df -h / | tail -1 | awk '{print $5}' | sed 's/%//')
# ネットワーク統計(プライマリインターフェースを動的検出)
local primary_interface=$(awk -F':' '/:/ {if ($1 !~ /lo/ && $2 !~ /^ *0/) {gsub(/^ */, "", $1); print $1; exit}}' /proc/net/dev)
local net_rx=$(cat /proc/net/dev | grep "$primary_interface" | awk '{print $2}')
local net_tx=$(cat /proc/net/dev | grep "$primary_interface" | awk '{print $10}')
# プロセス数
local proc_count=$(ps aux | wc -l)
# JSON形式で出力
echo "{
\"timestamp\": \"$timestamp\",
\"cpu_usage\": $cpu_usage,
\"mem_usage\": $mem_usage,
\"disk_usage\": $disk_usage,
\"network\": {\"rx_bytes\": $net_rx, \"tx_bytes\": $net_tx},
\"process_count\": $proc_count
}" | tee -a "$LOG_FILE"
# アラート判定
check_alerts "$cpu_usage" "$mem_usage" "$disk_usage"
}
# アラート判定関数
check_alerts() {
local cpu=$1
local mem=$2
local disk=$3
if (( $(echo "$cpu > $ALERT_CPU" | bc -l) )); then
send_alert "CPU" "$cpu%"
fi
if (( $(echo "$mem > $ALERT_MEM" | bc -l) )); then
send_alert "Memory" "$mem%"
fi
if [ "$disk" -gt "$ALERT_DISK" ]; then
send_alert "Disk" "$disk%"
fi
}
# アラート送信関数
send_alert() {
local metric=$1
local value=$2
local message="ALERT: $metric usage is $value ($(date))"
echo "$message" | tee -a "$LOG_FILE"
# 実際の通知(メール、Slack等)はここに実装
}
# メイン監視ループ
main() {
echo "Starting system monitoring..."
echo "Press Ctrl+C to stop"
trap 'echo "Monitoring stopped"; exit 0' SIGINT SIGTERM
while true; do
clear
echo "=== System Performance Dashboard ==="
echo "Time: $(date)"
echo
collect_metrics
sleep 5
done
}
main "$@"
4.8 まとめ:CUIマスターへの道
CUIスキルの段階的習得
レベル1:基本コマンドを覚える
ls, cd, cp, mv, rm, cat, grep, less
レベル2:パイプとリダイレクトを使いこなす
command1 | command2 > output.txt 2>&1
レベル3:シェルスクリプトを書く
#!/bin/bash
# 条件分岐、ループ、関数を含むスクリプト
レベル4:高度なテキスト処理
sed, awk, perl one-liners
レベル5:システム全体の自動化
# CI/CD、監視、デプロイメントの自動化
CUIがもたらす本質的な価値
- 思考の速度で操作できる:タイピングさえ速ければ、思考と同じ速度で操作可能
- 完全な再現性:同じコマンドは常に同じ結果を生む
- 無限の組み合わせ:小さなコマンドから複雑な処理を構築
- どこでも同じ:ローカルでもリモートでも同じ操作
次章への橋渡し
CUIを使いこなすということは、複数のプログラムを協調させて動かすということです。次章では、これらのプログラム(プロセス)がどのように生成され、実行され、終了するのかを学びます。
プロセスの理解は、システムの動作を理解する上で不可欠です。なぜなら、Linuxシステムで起きるすべてのことは、プロセスの振る舞いとして説明できるからです。
章末演習問題
問題1:基本理解の確認
以下の文章の空欄を埋めてください。
- シェルは人間と( )の間に立つ( )の役割を果たします。
-
パイプ( )は、あるコマンドの( )を別のコマンドの( )につなぎます。 - リダイレクトで、標準出力は( )、標準エラー出力は( )、両方を同じファイルに出力するには( )と記述します。
問題2:コマンドの理解
次のコマンドが何をするか説明してください。
find /var/log -name "*.log" -mtime +30 -exec rm {} \;
ps aux | grep nginx | grep -v grep | awk '{print $2}' | xargs kill -HUP
tail -f /var/log/syslog | grep -E "error|warning" | tee alerts.log
問題3:実践的な課題
以下のタスクを実現するコマンドまたはシェルスクリプトを作成してください。
-
カレントディレクトリ以下のすべての.txtファイルの中から、”TODO”という文字列を含む行を、ファイル名と行番号付きで表示する。
-
直近1時間のシステムログ(/var/log/syslog)から、各ログレベル(ERROR、WARNING、INFO)の出現回数を集計して表示する。
-
指定したディレクトリ内の各サブディレクトリのディスク使用量を計算し、使用量の多い順に上位10個を表示する。
問題4:パイプラインの設計
次の要件を満たすコマンドパイプラインを設計してください。
Webサーバーのアクセスログ(/var/log/nginx/access.log)から:
- 本日のアクセスのみを抽出
- ステータスコード404のものだけを選択
- アクセス元IPアドレスごとに集計
- 多い順に並べ替え
- 上位20件を表示
問題5:シェルスクリプトの作成
以下の機能を持つシェルスクリプトを作成してください。
#!/bin/bash
# log_monitor.sh - ログファイル監視スクリプト
# 要件:
# 1. 引数でログファイルのパスを受け取る
# 2. そのファイルをリアルタイムで監視
# 3. "ERROR"という文字列が現れたら、その行を error_$(date +%Y%m%d).log に追記
# 4. 1分間にERRORが10回以上出現したら、アラートメッセージを表示
# 5. Ctrl+Cで終了時に、総ERROR数を表示
# ここにコードを記述
問題6:トラブルシューティング
以下のシェルスクリプトにはバグがあります。問題を特定し、修正してください。
#!/bin/bash
# ディスク使用率が80%を超えたらアラートを出すスクリプト
threshold=80
df -h | grep -v "Filesystem" | while read line
do
usage=$(echo $line | awk '{print $5}' | sed 's/%//')
mount=$(echo $line | awk '{print $6}')
if [ $usage > $threshold ]; then
echo "Warning: $mount is $usage% full"
fi
done
問題7:発展的課題
-
GUIとCUIのそれぞれの利点と欠点を整理し、どのような場面でどちらを選択すべきか、あなたの考えを述べてください。
-
現代のDevOpsやSREの文脈において、シェルスクリプトがどのように活用されているか、具体例を挙げて説明してください。