Files
linux-bash/port-info/port_info.sh
2026-02-17 17:28:37 +08:00

261 lines
12 KiB
Bash
Executable File

#!/bin/bash
#===============================================================================
# Linux 端口信息查看脚本
# 兼容: Ubuntu / Debian 及衍生版
# 功能: 显示 TCP、UDP、HTTP 端口服务信息
#===============================================================================
##
RED='\033[38;5;196m'
GREEN='\033[38;5;46m'
YELLOW='\033[38;5;226m'
BLUE='\033[38;5;21m'
MAGENTA='\033[38;5;201m'
CYAN='\033[38;5;51m'
WHITE='\033[38;5;255m'
ORANGE='\033[38;5;208m'
PINK='\033[38;5;219m'
LIME='\033[38;5;154m'
PURPLE='\033[38;5;141m'
GOLD='\033[38;5;220m'
GRAY='\033[38;5;244m'
NC='\033[0m'
SEPARATOR="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
#===============================================================================
check_commands() {
# echo -e "${CYAN}▸ 检测命令...${NC}"
if command -v ss &> /dev/null; then
PORT_CMD="ss"
elif command -v netstat &> /dev/null; then
PORT_CMD="netstat"
else
echo -e "${RED}✗ 错误: 未找到 ss 或 netstat 命令${NC}"
echo -e "${YELLOW} 请安装: apt-get install net-tools${NC}"
exit 1
fi
# echo -e "${GREEN}✓ 使用命令: ${PORT_CMD}${NC}"
}
#===============================================================================
##
get_service_name() {
local port=$1
case $port in
20) echo "FTP-DATA" ;;
21) echo "FTP" ;;
22) echo "SSH" ;;
23) echo "Telnet" ;;
25) echo "SMTP" ;;
53) echo "DNS" ;;
67|68) echo "DHCP" ;;
80) echo "HTTP" ;;
110) echo "POP3" ;;
123) echo "NTP" ;;
443) echo "HTTPS" ;;
3306) echo "MySQL" ;;
3389) echo "RDP" ;;
5432) echo "PostgreSQL" ;;
6379) echo "Redis" ;;
8080) echo "HTTP-Proxy" ;;
8443) echo "HTTPS-Alt" ;;
27017) echo "MongoDB" ;;
*) echo "未知" ;;
esac
}
#===============================================================================
show_tcp_ports() {
echo -e "\n${SEPARATOR}"
echo -e "${BLUE} 🔵 TCP 端口监听列表 ${NC}"
echo -e "${SEPARATOR}"
printf "${GREEN}%-6s %-10s %-14s %-10s %-20s${NC}\n" "协议" "端口" "服务(参考)" "PID" "进程名称"
echo -e "${GRAY}──────────────────────────────────────────────────────────────────────────────${NC}"
if [ "$PORT_CMD" = "ss" ]; then
ss -tulnp 2>/dev/null | grep LISTEN | while IFS= read -r line; do
addr=$(echo "$line" | awk '{print $5}')
port="${addr##*:}"
[[ "$port" =~ ^[0-9]+$ ]] || continue
prog_field=$(echo "$line" | awk '{print $NF}')
pid=$(echo "$prog_field" | grep -oP 'pid=\K[0-9]+' | head -1)
name=$(echo "$prog_field" | sed -n 's/.*("\([^"]*\)".*/\1/p' | head -1)
[ -z "$pid" ] && pid="-"
[ -z "$name" ] && name="-"
service=$(get_service_name "$port")
printf "TCP|%-10s|%-14s|%-10s|%-20s\n" "$port" "$service" "$pid" "$name"
done | sort -t'|' -k2 -n | uniq | while IFS='|' read -r p s rv pi n; do
printf "${LIME}%-6s${NC} %-10s${NC} %-14s${NC} %-10s${NC} %-20s${NC}\n" "$p" "$s" "$rv" "$pi" "$n"
done
else
netstat -tulnp 2>/dev/null | grep LISTEN | while read -r line; do
port=$(echo "$line" | awk '{split($4,a,":"); print a[length(a)]}')
[[ "$port" =~ ^[0-9]+$ ]] || continue
prog=$(echo "$line" | awk '{print $NF}')
pid=$(echo "$prog" | cut -d'/' -f1)
name=$(echo "$prog" | cut -d'/' -f2 | cut -d' ' -f1)
[ -z "$pid" ] && pid="-"
[ -z "$name" ] && name="-"
service=$(get_service_name "$port")
printf "TCP|%-10s|%-14s|%-10s|%-20s\n" "$port" "$service" "$pid" "$name"
done | sort -t'|' -k2 -n | uniq | while IFS='|' read -r p s rv pi n; do
printf "${LIME}%-6s${NC} %-10s${NC} %-14s${NC} %-10s${NC} %-20s${NC}\n" "TCP" "$p" "$s" "$pi" "$n"
done
fi
echo -e "${GRAY}──────────────────────────────────────────────────────────────────────────────${NC}"
}
#===============================================================================
show_udp_ports() {
echo -e "\n${SEPARATOR}"
echo -e "${MAGENTA} 🟣 UDP 端口监听列表 ${NC}"
echo -e "${SEPARATOR}"
printf "${PINK}%-6s %-10s %-14s %-10s %-20s${NC}\n" "协议" "端口" "服务(参考)" "PID" "进程名称"
echo -e "${GRAY}──────────────────────────────────────────────────────────────────────────────${NC}"
if [ "$PORT_CMD" = "ss" ]; then
ss -ulnp 2>/dev/null | awk 'NR>1 && $1!="State"' | while IFS= read -r line; do
addr=$(echo "$line" | awk '{print $4}')
port="${addr##*:}"
[[ "$port" =~ ^[0-9]+$ ]] || continue
prog_field=$(echo "$line" | awk '{print $NF}')
pid=$(echo "$prog_field" | grep -oP 'pid=\K[0-9]+' | head -1)
name=$(echo "$prog_field" | sed -n 's/.*("\([^"]*\)".*/\1/p' | head -1)
[ -z "$pid" ] && pid="-"
[ -z "$name" ] && name="-"
service=$(get_service_name "$port")
printf "UDP|%-10s|%-14s|%-10s|%-20s\n" "$port" "$service" "$pid" "$name"
done | sort -t'|' -k2 -n | uniq | while IFS='|' read -r p s rv pi n; do
printf "${LIME}%-6s${NC} %-10s${NC} %-14s${NC} %-10s${NC} %-20s${NC}\n" "$p" "$s" "$rv" "$pi" "$n"
done
else
netstat -ulnp 2>/dev/null | awk 'NR>1' | while read -r line; do
port=$(echo "$line" | awk '{split($4,a,":"); print a[length(a)]}')
[[ "$port" =~ ^[0-9]+$ ]] || continue
prog=$(echo "$line" | awk '{print $NF}')
pid=$(echo "$prog" | cut -d'/' -f1)
name=$(echo "$prog" | cut -d'/' -f2 | cut -d' ' -f1)
[ -z "$pid" ] && pid="-"
[ -z "$name" ] && name="-"
service=$(get_service_name "$port")
printf "UDP|%-10s|%-14s|%-10s|%-20s\n" "$port" "$service" "$pid" "$name"
done | sort -t'|' -k2 -n | uniq | while IFS='|' read -r p s rv pi n; do
printf "${LIME}%-6s${NC} %-10s${NC} %-14s${NC} %-10s${NC} %-20s${NC}\n" "$p" "$s" "$rv" "$pi" "$n"
done
fi
echo -e "${GRAY}──────────────────────────────────────────────────────────────────────────────${NC}"
}
#===============================================================================
show_http_ports() {
echo -e "\n${SEPARATOR}"
echo -e "${YELLOW} 🟡 HTTP/HTTPS 常用端口 ${NC}"
echo -e "${SEPARATOR}"
printf "${ORANGE}%-6s %-10s %-14s %-10s %-10s %-20s${NC}\n" "协议" "端口" "服务(参考)" "状态" "PID" "进程名称"
echo -e "${GRAY}────────────────────────────────────────────────────────────────────────────────────────${NC}"
http_ports="80 443 8080 8443 8000 8888 3000 5000"
for port in $http_ports; do
if [ "$PORT_CMD" = "ss" ]; then
result=$(ss -tulnp 2>/dev/null | grep ":$port " | grep -v grep)
if [ -n "$result" ]; then
proto=$(echo "$result" | awk '{print $1}' | head -1 | tr '[:upper:]' '[:lower:]')
prog_field=$(echo "$result" | awk '{print $NF}')
pid=$(echo "$prog_field" | grep -oP 'pid=\K[0-9]+' | head -1)
name=$(echo "$prog_field" | sed -n 's/.*("\([^"]*\)".*/\1/p' | head -1)
[ -z "$pid" ] && pid="-"
[ -z "$name" ] && name="-"
service=$(get_service_name "$port")
printf "${LIME}%-6s${NC} %-10s${NC} %-14s${NC} %-10s${NC} %-10s${NC} %-20s${NC}\n" "$proto" "$port" "$service" "监听中" "$pid" "$name"
fi
else
result=$(netstat -tulnp 2>/dev/null | grep ":$port " | grep -v grep)
if [ -n "$result" ]; then
proto=$(echo "$result" | awk '{print $6}' | head -1 | tr '[:upper:]' '[:lower:]')
prog=$(echo "$result" | awk '{print $7}')
pid=$(echo "$prog" | cut -d'/' -f1)
name=$(echo "$prog" | cut -d'/' -f2 | cut -d' ' -f1)
[ -z "$pid" ] && pid="-"
[ -z "$name" ] && name="-"
service=$(get_service_name "$port")
printf "${LIME}%-6s${NC} %-10s${NC} %-14s${NC} %-10s${NC} %-10s${NC} %-20s${NC}\n" "$proto" "$port" "$service" "监听中" "$pid" "$name"
fi
fi
done
echo -e "${GRAY}────────────────────────────────────────────────────────────────────────────────────────${NC}"
echo -e "${GRAY}※ 服务(参考) 列为常用端口的默认服务名称,仅供参考,实际占用程序以进程名称列为准${NC}"
}
#===============================================================================
show_statistics() {
echo -e "\n${SEPARATOR}"
echo -e "${CYAN} 📊 端口统计信息 ${NC}"
echo -e "${SEPARATOR}"
if [ "$PORT_CMD" = "ss" ]; then
tcp_count=$(ss -tuln 2>/dev/null | grep -c LISTEN)
udp_count=$(ss -uln 2>/dev/null | awk 'NR>1 && $1 != "State" && /:[0-9]+/ {print}' | wc -l)
else
tcp_count=$(netstat -tuln 2>/dev/null | grep -c LISTEN)
udp_count=$(netstat -uln 2>/dev/null | awk 'NR>1 && /:[0-9]+/ {print}' | wc -l)
fi
total=$((tcp_count + udp_count))
printf " ${BLUE}TCP 监听端口:${NC} ${GREEN}%d${NC}\n" "$tcp_count"
printf " ${MAGENTA}UDP 监听端口:${NC} ${GREEN}%d${NC}\n" "$udp_count"
printf " ${YELLOW}总 计:${NC} ${ORANGE}%d${NC}\n" "$total"
}
#===============================================================================
show_header() {
clear
echo -e ""
echo -e "${SEPARATOR}"
echo -e "${PURPLE} ║ Linux 系统端口信息查看工具${NC}"
echo -e "${SEPARATOR}"
echo -e " ${GOLD}▸ 兼容系统:${NC} ${WHITE}Ubuntu / Debian 及衍生版本${NC}"
echo -e " ${GOLD}▸ 生成时间:${NC} ${WHITE}$(date '+%Y-%m-%d %H:%M:%S')${NC}"
echo -e "${SEPARATOR}"
}
#===============================================================================
main() {
show_header
check_commands
show_tcp_ports
show_udp_ports
show_http_ports
show_statistics
}
main