一键查看 Docker 容器详情:Bash 脚本实现及功能解析

Docker 容器信息查看 Bash 脚本详解

本文介绍一款实用的 Bash 脚本,用于列出本机所有 Docker 容器,并支持用户选择单个容器查看其详细信息,包括网络模式、端口映射、挂载路径、状态及资源占用情况,同时还会计算挂载路径的实际磁盘占用。


一、脚本源码

#!/bin/bash

# 定义颜色代码
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 检查是否安装了 docker
if ! command -v docker > /dev/null; then
    echo -e "${RED}错误: Docker 未安装,请先安装 Docker!${NC}"
    exit 1
fi

# 获取所有容器 ID 和名称
containers=$(docker ps -a --format "{{.ID}} {{.Names}}")

if [ -z "$containers" ]; then
    echo -e "${YELLOW}警告: 当前没有运行或存在的容器!${NC}"
    exit 0
fi

# 列出所有容器
echo -e "${BLUE}===== 当前 Docker 容器列表 =====${NC}"
declare -A container_map
index=1
while IFS=' ' read -r id name; do
    echo -e "${YELLOW}$index. $name${NC} (ID: $id)"
    container_map[$index]="$id"
    ((index++))
done <<< "$containers"
echo -e "${BLUE}------------------------${NC}"

# 提示用户选择容器
echo -e "请输入要查看的容器序号 (1-${#container_map[@]}),或输入 'q' 退出:"
read choice

if [ "$choice" == "q" ] || [ "$choice" == "Q" ]; then
    echo -e "${GREEN}已退出${NC}"
    exit 0
fi

# 检查输入是否有效
if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "${#container_map[@]}" ]; then
    echo -e "${RED}错误: 无效的序号!${NC}"
    exit 1
fi

# 获取选中的容器 ID
container_id="${container_map[$choice]}"
name=$(docker inspect --format '{{.Name}}' "$container_id" | sed 's|/||')

# 显示容器详细信息
echo -e "\n${BLUE}===== 容器详细信息: $name =====${NC}"
echo -e "容器 ID: $container_id"

# 获取网络模式
network_mode=$(docker inspect --format '{{.HostConfig.NetworkMode}}' "$container_id")
echo -e "网络模式: ${YELLOW}$network_mode${NC}"

if [ "$network_mode" == "host" ]; then
    echo -e "${GREEN}网络类型: Host 模式 (直接使用主机网络)${NC}"
    host_ip=$(hostname -i)
    echo -e "主机 IP: $host_ip"
    pid=$(docker inspect --format '{{.State.Pid}}' "$container_id")
    if [ -n "$pid" ] && [ "$pid" != "0" ]; then
        ports=$(ss -tulnp 2>/dev/null | grep "pid=$pid" | awk '{print $5}' | awk -F: '{print $NF}' | sort -u | tr '\n' ' ')
        if [ -n "$ports" ]; then
            echo -e "容器监听端口: ${YELLOW}$ports${NC}"
        else
            echo -e "容器监听端口: ${RED}未检测到开放端口${NC}"
        fi
    else
        echo -e "容器监听端口: ${RED}无法获取容器 PID${NC}"
    fi
else
    echo -e "${RED}网络类型: 非 Host 模式${NC}"
    ports_mapping=$(docker inspect --format '{{if .NetworkSettings.Ports}}{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$p}} -> {{(index $conf 0).HostPort}} {{end}}{{end}}{{end}}' "$container_id" 2>/dev/null)
    if [ -n "$ports_mapping" ]; then
        echo -e "端口映射: ${YELLOW}$ports_mapping${NC}"
    else
        echo -e "端口映射: ${YELLOW}无${NC}"
    fi
    container_ip=$(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_id")
    echo -e "容器 IP: $container_ip"
fi

echo -e "挂载路径:"
mounts=$(docker inspect --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{\"\n\"}}{{end}}' "$container_id")
if [ -n "$mounts" ]; then
    echo -e "${BLUE}$mounts${NC}" | sed 's/^/  /'
else
    echo -e "  无"
fi

status=$(docker inspect --format '{{.State.Status}}' "$container_id")
echo -e "容器状态: ${GREEN}$status${NC}"

echo -e "\n${BLUE}===== 资源占用信息 =====${NC}"
mem_usage=$(docker stats --no-stream --format "{{.MemUsage}}" "$container_id")
cpu_perc=$(docker stats --no-stream --format "{{.CPUPerc}}" "$container_id")
if [ -n "$mem_usage" ] && [ -n "$cpu_perc" ]; then
    echo -e "内存占用: ${YELLOW}$mem_usage${NC}"
    echo -e "CPU 占用: ${YELLOW}$cpu_perc${NC}"
else
    echo -e "${RED}无法获取资源占用信息,容器可能未运行${NC}"
fi

# 计算挂载路径的实际磁盘占用并对齐显示
echo -e "挂载路径磁盘占用:"
if [ -n "$mounts" ]; then
    total_size=0
    echo "$mounts" > /tmp/mounts_temp_$$
    # 打印表头
    printf "  ${BLUE}%-42s${NC} ${YELLOW}%10s${NC}\n" "路径" "占用大小"
    echo "  -------------------------------------------------- ----------"
    while read -r line; do
        source=$(echo "$line" | awk -F ' -> ' '{print $1}')
        if [ -d "$source" ] || [ -f "$source" ]; then
            size=$(du -sb "$source" | awk '{print $1}')
            size_human=$(echo "$size" | numfmt --to=iec --suffix=B)
            printf "  ${BLUE}%-42s${NC} ${YELLOW}%10s${NC}\n" "$source" "$size_human"
            total_size=$((total_size + size))
        else
            printf "  ${BLUE}%-42s${NC} ${RED}%10s${NC}\n" "$source" "路径不存在"
        fi
    done < /tmp/mounts_temp_$$
    rm -f /tmp/mounts_temp_$$
    total_size_human=$(echo "$total_size" | numfmt --to=iec --suffix=B)
    echo "  -------------------------------------------------- ----------"
    printf "  %-42s ${YELLOW}%10s${NC}\n" "总占用" "$total_size_human"
else
    echo -e "  ${RED}无挂载路径,无法计算占用${NC}"
fi

echo -e "\n${BLUE}===== 检查完成 =====${NC}"

二、脚本功能解析

  • 颜色显示:使用 ANSI 转义码美化输出,红色表示错误,绿色表示成功,黄色提示,蓝色作标题。
  • Docker 命令检测:开头检测 Docker 是否安装,避免脚本误执行。
  • 容器列表:列出所有容器编号及名称,支持交互式选择查看详情。
  • 网络信息:区分 Host 模式和非 Host 模式网络,展示对应的 IP 地址和端口映射。
  • 挂载路径:显示容器的挂载源路径及目标路径,支持多挂载点。
  • 资源监控:使用 docker stats 获取内存和 CPU 使用率,实时展示。
  • 挂载路径磁盘占用:计算并显示每个挂载路径在宿主机上的磁盘占用,支持文件和目录,末尾汇总总占用。

三、使用说明

  1. 保存脚本(如 docker_container_info.sh),赋予执行权限:chmod +x docker_container_info.sh
  2. 确认当前用户具备执行 Docker 命令权限(建议加入 docker 用户组)。
  3. 执行脚本:./docker_container_info.sh
  4. 根据提示输入容器序号查看详情,或输入 q 退出。

四、示例输出


===== 当前 Docker 容器列表 =====
1. my-nginx (ID: abcd1234)
2. redis-server (ID: efgh5678)
------------------------
请输入要查看的容器序号 (1-2),或输入 'q' 退出:
1

===== 容器详细信息: my-nginx =====
容器 ID: abcd1234
网络模式: host
网络类型: Host 模式 (直接使用主机网络)
主机 IP: 192.168.0.100
容器监听端口: 80 443
挂载路径:
  /var/lib/nginx/conf -> /etc/nginx/conf.d
容器状态: running

===== 资源占用信息 =====
内存占用: 25MiB / 512MiB
CPU 占用: 0.2%

挂载路径磁盘占用:
  路径                                          占用大小
  -------------------------------------------------- ----------
  /var/lib/nginx/conf                           1.2MiB
  -------------------------------------------------- ----------
  总占用                                         1.2MiB

===== 检查完成 =====

五、总结

该脚本便于运维人员快速查询容器运行状态及资源占用,特别适合本地或多容器环境排查问题。同时结合颜色输出提高可读性,直观显示关键信息。

posted @ 2025-06-20 16:17  浒多年以后  阅读(84)  评论(0)    收藏  举报