以前のシェルスクリプト、メモリとCPU使用率を見るスクリプトを改修しました。
改修後のスクリプト
#!/bin/bash
# スクリプト名: top_procs.sh
# 説明: システム全体の負荷状況と、CPU/メモリ使用率が高い上位プロセスを表示します。
# 表示するプロセス数の設定
TOP_N=5
# ヘルプ表示関数
show_help() {
echo "--- プロセス監視スクリプト ---"
echo "このスクリプトは、システム全体の負荷状況(CPU/メモリ/LoadAvg)と、"
echo "リソース消費が多い上位${TOP_N}つのプロセスを表示します。"
echo ""
echo "使用方法: $0 [オプション]"
echo ""
echo "オプション:"
echo " -c : CPU使用率 (%\$CPU) の高い上位${TOP_N}つのプロセスを表示します。"
echo " -m : メモリ使用率 (%\$MEM) の高い上位${TOP_N}つのプロセスを表示します。"
echo " -a : CPUとメモリの両方の上位${TOP_N}つのプロセスを表示します。(引数なしと同じ)"
echo " -h : このヘルプを表示します。"
echo ""
echo "出力形式: 割合(%) PID COMMAND"
echo "-----------------------------------------"
}
# システム全体のリソース状況表示関数
show_system_summary() {
echo "--- システム稼働状況 ---"
# 1. Load Average (uptimeコマンドから抽出)
# 出力例: 16:45:23 up 10 days, ... load average: 0.05, 0.03, 0.01
local load_avg=$(uptime | awk -F'load average:' '{ print $2 }' | xargs)
echo "Load Average : $load_avg"
# 2. CPU使用率 (vmstatコマンドから直近1秒の状態を取得)
# vmstat 1 2 の2行目(最新の状態)を取得し、アイドル率($15)を100から引く
if command -v vmstat >/dev/null 2>&1; then
local cpu_idle=$(vmstat 1 2 | tail -1 | awk '{print $15}')
local cpu_usage=$((100 - cpu_idle))
echo "CPU Usage : ${cpu_usage}%"
else
echo "CPU Usage : (vmstatコマンドが見つかりません)"
fi
# 3. メモリ使用率 (freeコマンドから計算)
# free -m の出力を解析
if command -v free >/dev/null 2>&1; then
local mem_info=$(free -m | grep Mem:)
local mem_total=$(echo "$mem_info" | awk '{print $2}')
local mem_used=$(echo "$mem_info" | awk '{print $3}')
# awkで浮動小数点計算
local mem_pct=$(awk "BEGIN {printf \"%.1f\", ${mem_used}/${mem_total}*100}")
echo "Memory Usage : ${mem_pct}% (${mem_used}MB / ${mem_total}MB)"
else
echo "Memory Usage : (freeコマンドが見つかりません)"
fi
echo "------------------------"
}
# プロセス情報表示関数
# 引数1: ソート対象 (CPU/MEM)
# 引数2: ソートフィールド番号 (ps auxの3番目か4番目)
# 引数3: タイトル
show_top_procs() {
local type=$1
local field=$2
local title=$3
echo ""
echo "--- ${title} (上位 ${TOP_N} プロセス) ---"
echo " %${type} PID COMMAND"
echo "-----------------------------------------"
ps aux |
# ヘッダー行をスキップ
tail -n +2 |
# 指定フィールド (CPU:%3, MEM:%4) で降順ソート
sort -k ${field} -r |
# 上位N行を抽出
head -n ${TOP_N} |
# PID ($2)、割合 ($field)、COMMAND ($11以降) を整形して表示
awk -v field="${field}" '{
cmd="";
for(i=11;i<=NF;i++){
cmd=cmd" "$i
};
# $fieldには$3(%CPU)または$4(%MEM)の値が入る
printf "%6.2f%% %6s %s\n", $field, $2, cmd
}'
}
# メインロジック
# まずシステム全体のサマリーを表示 (ヘルプ以外の場合)
if [ "$1" != "-h" ]; then
show_system_summary
fi
if [ "$#" -eq 0 ] || [ "$1" == "-a" ]; then
# 引数なし、または -a の場合 (全て表示)
show_top_procs "CPU" 3 "CPU使用率"
show_top_procs "MEM" 4 "メモリ使用率"
elif [ "$1" == "-c" ]; then
# -c の場合 (CPUのみ)
show_top_procs "CPU" 3 "CPU使用率"
elif [ "$1" == "-m" ]; then
# -m の場合 (メモリのみ)
show_top_procs "MEM" 4 "メモリ使用率"
elif [ "$1" == "-h" ]; then
# -h の場合 (ヘルプ)
show_help
else
# 不正な引数の場合
echo "不正なオプションです: $1" >&2
show_help
exit 1
fi
あとはこれに
chmod +x top-proc.sh
で実行権を付与します。
使用例
./top-proc.sh
--- システム稼働状況 ---
Load Average : 1.30, 1.40, 1.32
CPU Usage : 23%
Memory Usage : 60.5% (3583MB / 5920MB)
------------------------
--- CPU使用率 (上位 5 プロセス) ---
%CPU PID COMMAND
-----------------------------------------
52.10% 12345 ruby_app_server: /var/www/webapp1 (production)
9.40% 1086 /usr/sbin/database_server [...]
3.80% 42162 /usr/sbin/web_server -k start
1.50% 42161 /usr/sbin/web_server -k start
0.90% 7978 nodejs_process /path/to/nodejs_app/server.js
--- メモリ使用率 (上位 5 プロセス) ---
%MEM PID COMMAND
-----------------------------------------
13.10% 1984 /usr/bin/java -Xms256m -Xmx256m [...] search_engine -Des.path.home=/usr/share/search_engine [...]
10.00% 1086 /usr/sbin/database_server [...]
7.50% 12345 ruby_app_server: /var/www/webapp1 (production)
3.90% 78630 ruby_app_server: /var/www/webapp2 (production)
3.80% 76583 ruby_app_server: /var/www/webapp3 (production)
と出てきます。
- ロードアベレージ:uptimeコマンドから
- CPU使用率:vmstatコマンドから直近1秒
として、より現実値に近づけています。
sudo ln -sf /path/to/script/top-procs.sh /usr/local/bin/top-procs
として、どこからでもコマンドを呼び出せるようにしておくといいでしょう。(スクリプトの場所は自分がこれを保存した絶対パスを指定してください)
既にコマンド化している場合は、このスクリプトを差し替えるだけでOKです。
コメントを残す