外观
网络流量监控
约 1615 字大约 5 分钟
Shell网络监控流量统计运维工具
2026-01-16
实时监控网络接口流量,显示上传/下载速度和累计流量统计,支持多网卡监控。
功能特性
| 特性 | 说明 |
|---|---|
| 📊 实时监控 | 动态显示网络接口的上传/下载速率 |
| 🔍 自动检测 | 自动识别活跃的网络接口 |
| 🌐 多网卡 | 支持指定接口或查看所有接口统计 |
| 📈 流量统计 | 显示本次会话和累计流量 |
| 🎨 彩色输出 | 清晰的彩色界面 |
快速开始
# 下载脚本
curl -sL https://script.merma.cn/scripts/shell/MonitorScript/network_monitor.sh -o network_monitor.sh
chmod +x network_monitor.sh
# 自动检测接口,开始监控
./network_monitor.sh
# 监控指定接口
./network_monitor.sh -i eth0
# 每 2 秒刷新一次
./network_monitor.sh -i eth0 -n 2
# 监控 10 次后退出
./network_monitor.sh -c 10
# 查看累计流量统计
./network_monitor.sh -t
# 列出所有网络接口
./network_monitor.sh -l演示效果
================================================================================
网络流量实时监控
================================================================================
接口: eth0
状态: up
MAC: 00:16:3e:xx:xx:xx
IP: 192.168.1.100
时间: 2026-01-16 10:30:45
--------------------------------------------------------------------------------
下载 ↓ 上传 ↑ 总计
--------------------------------------------------------------------------------
当前速率 1.25 MB/s 256.00 KB/s
本次会话 45.67 MB 12.34 MB 58.01 MB
累计流量 2.35 GB 856.42 MB 3.18 GB
--------------------------------------------------------------------------------
刷新间隔: 1 秒 | 按 Ctrl+C 退出列出网络接口
可用网络接口:
接口 状态 MAC 地址 IP 地址
---------------------------------------------------------------------------
eth0 up 00:16:3e:xx:xx:xx 192.168.1.100
docker0 down 02:42:xx:xx:xx:xx 172.17.0.1参数说明
| 参数 | 说明 |
|---|---|
-i <interface> | 指定网络接口(默认自动检测) |
-n <seconds> | 刷新间隔秒数,默认 1 秒 |
-c <count> | 监控次数,0 为无限循环 |
-t | 显示累计流量统计后退出 |
-u <unit> | 显示单位:auto, B, K, M, G |
-l | 列出所有可用网络接口 |
-h | 显示帮助信息 |
环境要求
- 操作系统: Linux (RockyLinux, Ubuntu, Debian, CentOS)
- Shell: Bash 4.0+
- 依赖: coreutils, iproute2
脚本源码
点击展开查看完整源码
#!/bin/bash
#
# 网络流量监控脚本
# 功能: 实时监控网络接口流量,显示上传/下载速度和统计信息
# 兼容: RockyLinux, Ubuntu, Debian, CentOS 等主流 Linux 发行版
#
set -o pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'
BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
INTERVAL=1; INTERFACE=""; COUNT=0; SHOW_TOTAL=false; UNIT="auto"
usage() {
cat << EOF
用法: $0 [选项]
选项:
-i <interface> 指定网络接口 (默认: 自动检测)
-n <seconds> 刷新间隔秒数 (默认: 1)
-c <count> 监控次数,0 为无限 (默认: 0)
-t 显示累计流量统计
-u <unit> 显示单位: auto, B, K, M, G (默认: auto)
-l 列出所有可用网络接口
-h 显示此帮助信息
EOF
exit 0
}
die() { echo -e "${RED}错误: $1${NC}" >&2; exit 1; }
check_interface() { [ -d "/sys/class/net/$1" ]; }
get_all_interfaces() {
local interfaces=()
for iface in /sys/class/net/*; do
iface=$(basename "$iface"); [ "$iface" = "lo" ] && continue
interfaces+=("$iface")
done
echo "${interfaces[@]}"
}
detect_active_interface() {
local iface=$(ip route show default 2>/dev/null | awk '/default/ {print $5}' | head -1)
[ -n "$iface" ] && check_interface "$iface" && { echo "$iface"; return 0; }
for iface in /sys/class/net/*; do
iface=$(basename "$iface"); [ "$iface" = "lo" ] && continue
[ "$(cat "/sys/class/net/${iface}/operstate" 2>/dev/null)" = "up" ] && { echo "$iface"; return 0; }
done
for iface in /sys/class/net/*; do
iface=$(basename "$iface"); [ "$iface" = "lo" ] && continue
echo "$iface"; return 0
done
return 1
}
list_interfaces() {
echo -e "\n${CYAN}可用网络接口:${NC}\n"
printf " %-15s %-10s %-18s %s\n" "接口" "状态" "MAC 地址" "IP 地址"
echo " ---------------------------------------------------------------------------"
for iface in /sys/class/net/*; do
iface=$(basename "$iface"); [ "$iface" = "lo" ] && continue
local state=$(cat "/sys/class/net/${iface}/operstate" 2>/dev/null || echo "unknown")
local mac=$(cat "/sys/class/net/${iface}/address" 2>/dev/null || echo "-")
local ip=$(ip addr show "$iface" 2>/dev/null | awk '/inet / {print $2}' | cut -d'/' -f1 | head -1)
[ -z "$ip" ] && ip="-"
[ "$state" = "up" ] && state_color="${GREEN}${state}${NC}" || state_color="${RED}${state}${NC}"
printf " %-15s %-10b %-18s %s\n" "$iface" "$state_color" "$mac" "$ip"
done; echo ""
}
get_traffic() {
local iface=$1
local rx=$(cat "/sys/class/net/${iface}/statistics/rx_bytes" 2>/dev/null)
local tx=$(cat "/sys/class/net/${iface}/statistics/tx_bytes" 2>/dev/null)
[ -z "$rx" ] || [ -z "$tx" ] && return 1
echo "$rx $tx"
}
format_bytes() {
local bytes=$1 unit=$2
case "$unit" in
B) echo "${bytes} B" ;;
K) awk "BEGIN {printf \"%.2f KB\", $bytes / 1024}" ;;
M) awk "BEGIN {printf \"%.2f MB\", $bytes / 1024 / 1024}" ;;
G) awk "BEGIN {printf \"%.2f GB\", $bytes / 1024 / 1024 / 1024}" ;;
*)
if [ "$bytes" -lt 1024 ]; then echo "${bytes} B"
elif [ "$bytes" -lt 1048576 ]; then awk "BEGIN {printf \"%.2f KB\", $bytes / 1024}"
elif [ "$bytes" -lt 1073741824 ]; then awk "BEGIN {printf \"%.2f MB\", $bytes / 1024 / 1024}"
else awk "BEGIN {printf \"%.2f GB\", $bytes / 1024 / 1024 / 1024}"; fi ;;
esac
}
format_rate() {
local bps=$1 unit=$2
case "$unit" in
B) echo "${bps} B/s" ;;
K) awk "BEGIN {printf \"%.2f KB/s\", $bps / 1024}" ;;
M) awk "BEGIN {printf \"%.2f MB/s\", $bps / 1024 / 1024}" ;;
G) awk "BEGIN {printf \"%.2f GB/s\", $bps / 1024 / 1024 / 1024}" ;;
*)
if [ "$bps" -lt 1024 ]; then echo "${bps} B/s"
elif [ "$bps" -lt 1048576 ]; then awk "BEGIN {printf \"%.2f KB/s\", $bps / 1024}"
elif [ "$bps" -lt 1073741824 ]; then awk "BEGIN {printf \"%.2f MB/s\", $bps / 1024 / 1024}"
else awk "BEGIN {printf \"%.2f GB/s\", $bps / 1024 / 1024 / 1024}"; fi ;;
esac
}
show_total_stats() {
local interfaces; [ -n "$INTERFACE" ] && interfaces=("$INTERFACE") || read -ra interfaces <<< "$(get_all_interfaces)"
echo -e "\n${CYAN}网络流量统计${NC}\n时间: $(date '+%Y-%m-%d %H:%M:%S')\n"
printf " %-15s %15s %15s %15s %15s\n" "接口" "接收流量" "发送流量" "接收包数" "发送包数"
echo " ---------------------------------------------------------------------------------"
local total_rx=0 total_tx=0
for iface in "${interfaces[@]}"; do
check_interface "$iface" || continue
local rx=$(cat "/sys/class/net/${iface}/statistics/rx_bytes" 2>/dev/null || echo 0)
local tx=$(cat "/sys/class/net/${iface}/statistics/tx_bytes" 2>/dev/null || echo 0)
local rxp=$(cat "/sys/class/net/${iface}/statistics/rx_packets" 2>/dev/null || echo 0)
local txp=$(cat "/sys/class/net/${iface}/statistics/tx_packets" 2>/dev/null || echo 0)
total_rx=$((total_rx + rx)); total_tx=$((total_tx + tx))
printf " %-15s %15s %15s %15s %15s\n" "$iface" "$(format_bytes "$rx" "$UNIT")" "$(format_bytes "$tx" "$UNIT")" "$rxp" "$txp"
done
echo " ---------------------------------------------------------------------------------"
printf " %-15s %15s %15s\n" "总计" "$(format_bytes "$total_rx" "$UNIT")" "$(format_bytes "$total_tx" "$UNIT")"; echo ""
}
monitor_realtime() {
local iface=$1 prev_rx=0 prev_tx=0 session_rx=0 session_tx=0 iteration=0
read -r prev_rx prev_tx <<< "$(get_traffic "$iface")"
trap 'echo ""; echo -e "${YELLOW}监控已停止${NC}"; exit 0' INT
while true; do
sleep "$INTERVAL"
read -r curr_rx curr_tx <<< "$(get_traffic "$iface")"
[ -z "$curr_rx" ] || [ -z "$curr_tx" ] && { echo -e "${RED}获取流量数据失败${NC}"; continue; }
local rx_rate=$(( (curr_rx - prev_rx) / INTERVAL ))
local tx_rate=$(( (curr_tx - prev_tx) / INTERVAL ))
[ "$rx_rate" -lt 0 ] && rx_rate=0; [ "$tx_rate" -lt 0 ] && tx_rate=0
session_rx=$((session_rx + (curr_rx - prev_rx))); session_tx=$((session_tx + (curr_tx - prev_tx)))
printf "\033[2J\033[H"
echo "================================================================================"
echo -e " ${CYAN}网络流量实时监控${NC}"
echo "================================================================================"
echo -e "\n 接口: ${BOLD}${iface}${NC}"
echo " 状态: $(cat "/sys/class/net/${iface}/operstate" 2>/dev/null)"
echo " 时间: $(date '+%Y-%m-%d %H:%M:%S')\n"
echo "--------------------------------------------------------------------------------"
printf " %-12s %18s %18s %18s\n" "" "下载 ↓" "上传 ↑" "总计"
echo "--------------------------------------------------------------------------------"
printf " ${GREEN}当前速率${NC} %18s %18s\n" "$(format_rate "$rx_rate" "$UNIT")" "$(format_rate "$tx_rate" "$UNIT")"
printf " ${BLUE}本次会话${NC} %18s %18s %18s\n" "$(format_bytes "$session_rx" "$UNIT")" "$(format_bytes "$session_tx" "$UNIT")" "$(format_bytes "$((session_rx + session_tx))" "$UNIT")"
printf " ${CYAN}累计流量${NC} %18s %18s %18s\n" "$(format_bytes "$curr_rx" "$UNIT")" "$(format_bytes "$curr_tx" "$UNIT")" "$(format_bytes "$((curr_rx + curr_tx))" "$UNIT")"
echo "--------------------------------------------------------------------------------"
echo -e "\n 刷新间隔: ${INTERVAL} 秒 | 按 ${YELLOW}Ctrl+C${NC} 退出"
prev_rx=$curr_rx; prev_tx=$curr_tx
((iteration++))
[ "$COUNT" -gt 0 ] && [ "$iteration" -ge "$COUNT" ] && { echo -e "\n${GREEN}已完成 $COUNT 次监控${NC}"; break; }
done
}
while getopts "i:n:c:u:tlh" opt; do
case $opt in
i) INTERFACE="$OPTARG" ;;
n) INTERVAL="$OPTARG"; [[ ! "$INTERVAL" =~ ^[0-9]+$ ]] || [ "$INTERVAL" -lt 1 ] && die "刷新间隔必须是大于 0 的整数" ;;
c) COUNT="$OPTARG"; [[ ! "$COUNT" =~ ^[0-9]+$ ]] && die "监控次数必须是非负整数" ;;
u) UNIT="$OPTARG"; case "$UNIT" in auto|B|K|M|G) ;; *) die "无效的单位" ;; esac ;;
t) SHOW_TOTAL=true ;; l) list_interfaces; exit 0 ;; h) usage ;; *) usage ;;
esac
done
[ "$SHOW_TOTAL" = true ] && { show_total_stats; exit 0; }
[ -z "$INTERFACE" ] && INTERFACE=$(detect_active_interface)
[ -z "$INTERFACE" ] && die "未找到可用的网络接口"
check_interface "$INTERFACE" || die "网络接口 '$INTERFACE' 不存在"
monitor_realtime "$INTERFACE"