Skip to content

Instantly share code, notes, and snippets.

@skypesky
Last active May 28, 2025 02:46
Show Gist options
  • Save skypesky/1a87d10097998e460fd9ca0d4dd7b920 to your computer and use it in GitHub Desktop.
Save skypesky/1a87d10097998e460fd9ca0d4dd7b920 to your computer and use it in GitHub Desktop.
function getswap {
# 定义过滤阈值(100MB = 102400 KB)
MIN_TOTAL_KB=102400 # 100MB
# 列宽定义(同前)
COLUMNS=$(tput cols 2>/dev/null || echo 80)
CONTAINER_WIDTH=20
TYPE_WIDTH=10
CMD_WIDTH=$((COLUMNS - 8 - 12 - 12 - 12 - CONTAINER_WIDTH - TYPE_WIDTH - 4))
[ $CMD_WIDTH -lt 40 ] && CMD_WIDTH=40
# 表头输出(同前)
printf "%8s %12s %12s %12s %-${CONTAINER_WIDTH}s %-${TYPE_WIDTH}s %-${CMD_WIDTH}s\n" \
"PID" "Swap" "Mem" "Total" "Container" "Type" "Command Line"
printf "%8s %12s %12s %12s %-${CONTAINER_WIDTH}s %-${TYPE_WIDTH}s %-${CMD_WIDTH}s\n" \
"" "" "" "" "$(printf '%.0s-' $(seq 1 $CONTAINER_WIDTH))" \
"$(printf '%.0s-' $(seq 1 $TYPE_WIDTH))" \
"$(printf '%.0s-' $(seq 1 $CMD_WIDTH))"
# 进程遍历与数据采集(修改过滤条件,添加nginx例外)
for PID in $(ls /proc/ | grep -E '^[0-9]+$'); do
DIR="/proc/$PID"
[ -d "$DIR" ] || continue
SWAP=$(grep -h 'Swap:' "$DIR/smaps" 2>/dev/null | awk '{sum+=$2} END {print sum}')
SWAP=${SWAP:-0}
MEM=$(grep -h 'Rss:' "$DIR/smaps" 2>/dev/null | awk '{sum+=$2} END {print sum}')
MEM=${MEM:-0}
TOTAL=$((SWAP + MEM))
CMDLINE=$(cat "$DIR/cmdline" 2>/dev/null | tr '\0' ' ' | sed 's/ $//' || ps -p "$PID" -o comm=)
# 判断并替换
if [[ $CMDLINE == *"sh -c function getswap"* ]]; then
CMDLINE="self"
fi
# 新过滤逻辑:只要swap存在,一律不准跳过;nginx进程强制显示
if [ $SWAP -gt 0 ] || echo "$CMDLINE" | grep -q 'nginx'; then
# 单位转换(同前)
SWAP_HUMAN=$(numfmt --to=iec-i --suffix=B $((SWAP * 1024)))
MEM_HUMAN=$(numfmt --to=iec-i --suffix=B $((MEM * 1024)))
TOTAL_HUMAN=$(numfmt --to=iec-i --suffix=B $((TOTAL * 1024)))
# 获取容器和命令行(同前)
CONTAINER=$(
(grep -oP 'docker/\K[^/]+' "$DIR/cgroup" 2>/dev/null || echo "") | head -n1 | \
xargs -I {} sh -c 'docker inspect --format "{{.Name}}" {} 2>/dev/null || echo ""' | \
sed 's/^\///'
)
# 进程类型识别:node则为Node.js,否则unknown
PROC_TYPE="unknown"
if echo "$CMDLINE" | grep -q 'node'; then
PROC_TYPE="Node.js"
fi
# 输出主进程(同前)
printf "%8d %12s %12s %12s %-${CONTAINER_WIDTH}s %-${TYPE_WIDTH}s %s\n" \
"$PID" "$SWAP_HUMAN" "$MEM_HUMAN" "$TOTAL_HUMAN" "$CONTAINER" "$PROC_TYPE" "$CMDLINE"
fi
done | sort -k2,2hr -k4,4hr # 按Swap降序,Total降序排序
# 汇总计算(同前)
OVERALL_SWAP=$(find /proc/ -maxdepth 1 -type d -name '[0-9]*' 2>/dev/null -exec sh -c 'grep -h "Swap:" "$1/smaps" 2>/dev/null | awk "{sum+=\$2} END {print sum}"' _ {} \; | awk '{sum+=$1} END {print sum}')
OVERALL_MEM=$(find /proc/ -maxdepth 1 -type d -name '[0-9]*' 2>/dev/null -exec sh -c 'grep -h "Rss:" "$1/smaps" 2>/dev/null | awk "{sum+=\$2} END {print sum}"' _ {} \; | awk '{sum+=$1} END {print sum}')
OVERALL_TOTAL=$((OVERALL_SWAP + OVERALL_MEM))
OVERALL_SWAP_HUMAN=$(numfmt --to=iec-i --suffix=B $((OVERALL_SWAP * 1024)))
OVERALL_MEM_HUMAN=$(numfmt --to=iec-i --suffix=B $((OVERALL_MEM * 1024)))
OVERALL_TOTAL_HUMAN=$(numfmt --to=iec-i --suffix=B $((OVERALL_TOTAL * 1024)))
printf "\nOverall Swap: %12s\nOverall Mem: %12s\nOverall Total:%12s\n" "$OVERALL_SWAP_HUMAN" "$OVERALL_MEM_HUMAN" "$OVERALL_TOTAL_HUMAN"
}
getswap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment