Files
dock/Docker 容器端口查看工具

274 lines
8.0 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Docker 容器端口查看工具
# 作者: 自动生成
# 功能: 查看 Docker 容器的端口映射和网络信息
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 显示帮助信息
show_help() {
cat << EOF
${GREEN}Docker 容器端口查看工具${NC}
${YELLOW}使用方法:${NC}
$0 [选项] [容器名称/ID]
${YELLOW}选项:${NC}
-a, --all 显示所有容器(包括停止的)
-r, --running 只显示运行中的容器(默认)
-l, --list 简洁列表模式
-d, --detailed 详细模式(显示所有信息)
-p, --port PORT 查找使用特定端口的容器
-n, --network 显示网络信息
-s, --stats 显示统计信息
-h, --help 显示此帮助信息
${YELLOW}示例:${NC}
$0 # 显示运行中容器的端口
$0 -a # 显示所有容器的端口
$0 -l # 简洁列表
$0 nginx # 查看特定容器
$0 -p 80 # 查找使用80端口的容器
$0 -n # 显示网络信息
$0 -s # 显示统计信息
${YELLOW}快捷键:${NC}
Enter - 刷新显示
Ctrl+C - 退出
EOF
}
# 检查 Docker 是否可用
check_docker() {
if ! command -v docker &> /dev/null; then
echo -e "${RED}错误: Docker 未安装或未在 PATH 中${NC}"
exit 1
fi
if ! docker info &> /dev/null; then
echo -e "${RED}错误: Docker 守护进程未运行或无权限${NC}"
echo "请确保 Docker 正在运行,并且你有执行权限"
exit 1
fi
}
# 显示容器端口列表
show_container_ports() {
local container_filter=$1
local show_all=$2
local list_mode=$3
local docker_cmd="docker ps --format \"table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\""
if [ "$show_all" = "true" ]; then
docker_cmd="docker ps -a --format \"table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\""
fi
if [ "$list_mode" = "true" ]; then
docker_cmd="docker ps --format \"{{.Names}}\t{{.Ports}}\""
fi
if [ -n "$container_filter" ]; then
echo -e "${CYAN}查找容器: $container_filter${NC}"
eval "$docker_cmd" | grep -E "(NAMES|$container_filter)"
else
eval "$docker_cmd"
fi
}
# 显示详细端口信息
show_detailed_ports() {
echo -e "${YELLOW}=== 详细端口信息 ===${NC}"
# 获取所有运行中容器
local containers=$(docker ps --format "{{.Names}}")
for container in $containers; do
echo -e "\n${GREEN}容器: $container${NC}"
echo -e "${CYAN}端口映射:${NC}"
docker port "$container"
echo -e "${CYAN}网络设置:${NC}"
docker inspect "$container" --format '{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}
{{end}}' | grep -v '^$'
done
}
# 查找使用特定端口的容器
find_port_usage() {
local port=$1
echo -e "${YELLOW}查找使用端口 $port 的容器...${NC}"
# 方法1: 使用 docker ps 查找
echo -e "${CYAN}方法1 - 通过端口映射查找:${NC}"
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep -E "0.0.0.0:$port|::$port|0.0.0.0:.*->.*:$port" || echo "未找到"
# 方法2: 检查每个容器的端口映射
echo -e "\n${CYAN}方法2 - 详细端口检查:${NC}"
local containers=$(docker ps --format "{{.Names}}")
local found=0
for container in $containers; do
local port_info=$(docker port "$container" | grep -E ":$port" || true)
if [ -n "$port_info" ]; then
echo -e "${GREEN}容器: $container${NC}"
echo "$port_info"
found=1
fi
done
if [ $found -eq 0 ]; then
echo "未找到使用端口 $port 的容器"
fi
# 方法3: 使用 netstat 检查主机端口
echo -e "\n${CYAN}方法3 - 主机端口使用情况:${NC}"
if command -v netstat &> /dev/null; then
netstat -tulpn | grep ":$port " || echo "主机上未发现该端口监听"
elif command -v ss &> /dev/null; then
ss -tulpn | grep ":$port " || echo "主机上未发现该端口监听"
else
echo "无法检查主机端口使用情况netstat/ss 不可用)"
fi
}
# 显示网络信息
show_network_info() {
echo -e "${YELLOW}=== Docker 网络信息 ===${NC}"
echo -e "\n${CYAN}网络列表:${NC}"
docker network ls
echo -e "\n${CYAN}容器网络详情:${NC}"
local containers=$(docker ps --format "{{.Names}}")
for container in $containers; do
echo -e "\n${GREEN}容器: $container${NC}"
docker inspect "$container" --format '{{range $net, $conf := .NetworkSettings.Networks}}
网络: {{$net}}
IP地址: {{$conf.IPAddress}}
网关: {{$conf.Gateway}}
MAC地址: {{$conf.MacAddress}}
{{end}}' | grep -v '^$'
done
}
# 显示统计信息
show_stats() {
echo -e "${YELLOW}=== Docker 统计信息 ===${NC}"
local total_containers=$(docker ps -q | wc -l)
local running_containers=$(docker ps -q --filter status=running | wc -l)
local stopped_containers=$(docker ps -q --filter status=exited | wc -l)
echo -e "${CYAN}容器统计:${NC}"
echo -e "总容器数: $total_containers"
echo -e "运行中: $running_containers"
echo -e "已停止: $stopped_containers"
echo -e "\n${CYAN}资源使用:${NC}"
docker stats --no-stream --format "table {{.Container}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}" | head -10
}
# 交互式模式
interactive_mode() {
echo -e "${GREEN}进入交互式模式 (按 Ctrl+C 退出)${NC}"
while true; do
echo -e "\n${YELLOW}选择操作:${NC}"
echo "1) 查看运行中容器端口"
echo "2) 查看所有容器端口"
echo "3) 简洁列表"
echo "4) 详细端口信息"
echo "5) 查找端口使用"
echo "6) 网络信息"
echo "7) 统计信息"
echo "8) 刷新显示"
echo "9) 退出"
read -p "请输入选择 (1-9): " choice
case $choice in
1) show_container_ports "" "false" "false" ;;
2) show_container_ports "" "true" "false" ;;
3) show_container_ports "" "false" "true" ;;
4) show_detailed_ports ;;
5)
read -p "请输入要查找的端口: " port
find_port_usage "$port"
;;
6) show_network_info ;;
7) show_stats ;;
8) clear; echo -e "${GREEN}显示已刷新${NC}" ;;
9) break ;;
*) echo -e "${RED}无效选择${NC}" ;;
esac
echo
read -p "按 Enter 继续..." dummy
clear
done
}
# 主函数
main() {
check_docker
# 如果没有参数,显示运行中容器
if [ $# -eq 0 ]; then
echo -e "${YELLOW}=== 运行中容器端口信息 ===${NC}"
show_container_ports "" "false" "false"
exit 0
fi
case $1 in
-a|--all)
show_container_ports "" "true" "false"
;;
-r|--running)
show_container_ports "" "false" "false"
;;
-l|--list)
show_container_ports "" "false" "true"
;;
-d|--detailed)
show_detailed_ports
;;
-p|--port)
if [ -z "$2" ]; then
echo -e "${RED}错误: 请指定要查找的端口${NC}"
exit 1
fi
find_port_usage "$2"
;;
-n|--network)
show_network_info
;;
-s|--stats)
show_stats
;;
-h|--help)
show_help
;;
-i|--interactive)
interactive_mode
;;
*)
# 如果参数不是选项,认为是容器名称
show_container_ports "$1" "false" "false"
;;
esac
}
# 运行主函数
main "$@"