docker-hub_images_check
Docker Hub 镜像标签查看工具
一键脚本
bash <(curl -sL gitee.com/meimolihan/cmdbox/raw/master/sh/docker-hub_images_check.sh) mobufan:dckr_pat_xxxxxx mobufan/cmdbox mobufan/metube-zh mobufan/speedtest-go-zh
bash <(curl -sL ../sh/docker-hub_images_check.sh) mobufan:dckr_pat_xxxxxx mobufan/cmdbox mobufan/metube-zh mobufan/speedtest-go-zh
补充说明
该脚本用于通过 Docker Hub 官方 API 查看指定镜像仓库的所有标签列表。支持多仓库同时查看、自动分页获取完整标签列表。
功能特点
- 支持单仓库或多仓库同时查看
- 自动分页获取所有标签(API 单次限制 100 条)
- 支持传参和交互式两种模式
- 按字母排序输出,便于快速浏览
- 彩色输出,仓库与标签区分显示
- 完善的错误处理(HTTP 状态码检查、JSON 校验)
参数说明
| 参数位置 | 说明 | 默认值 |
|---|---|---|
| 第 1 个参数(必需) | 用户名:PAT(如 mobufan:dckr_pat_xxxxxx) |
交互式输入 |
| 第 2 个及后续参数(可选) | 仓库名列表,空格分隔 | 默认为 mobufan/cmdbox |
用法示例
# 交互模式(依次输入 PAT 和仓库名)
bash docker-hub_images_check.sh
# 传参模式(单仓库)
bash docker-hub_images_check.sh mobufan:dckr_pat_xxxxxx mobufan/cmdbox
# 传参模式(多仓库)
bash docker-hub_images_check.sh mobufan:dckr_pat_xxxxxx mobufan/cmdbox mobufan/metube-zh mobufan/speedtest-go-zh
工作流程
输入 PAT / 用户名:PAT
↓
输入仓库名列表(多个用空格分隔)
↓
遍历每个仓库
↓
调用 Hub API 分页获取所有标签
↓
校验 HTTP 状态码和 JSON 格式
↓
输出完整标签列表(排序去重)
认证方式说明
| 认证方式 | 格式 | 说明 |
|---|---|---|
| 用户名:PAT | mobufan:dckr_pat_xxxxxx |
推荐方式,使用 Docker Hub 账户设置中生成的 PAT |
注意事项
- PAT 仅需要
read权限即可查看标签 - 脚本会自动处理分页,确保获取仓库所有标签
- 如果仓库标签较多(超过 100 个),脚本会自动请求后续页面
- 标签列表会自动排序去重
脚本源码
#!/bin/bash
set -uo pipefail
IFS=$'\n\t'
list_color_init() {
export gl_hui=$'\033[38;5;59m'
export gl_hong=$'\033[38;5;9m'
export gl_lv=$'\033[38;5;10m'
export gl_huang=$'\033[38;5;11m'
export gl_lan=$'\033[38;5;32m'
export gl_bai=$'\033[38;5;15m'
export gl_zi=$'\033[38;5;13m'
export gl_bufan=$'\033[38;5;14m'
export reset=$'\033[0m'
}
list_color_init
log_info() { echo -e "${gl_lan}[信息]${gl_bai} $*"; }
log_ok() { echo -e "${gl_lv}[成功]${gl_bai} $*"; }
log_warn() { echo -e "${gl_huang}[警告]${gl_bai} $*"; }
log_error() { echo -e "${gl_hong}[错误]${gl_bai} $*" >&2; }
exit_script() {
echo ""
echo -ne "${gl_hong}感谢使用,再见!${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep 0.5
echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep 0.6
clear
exit 0
}
break_end() {
echo -e "${gl_lv}操作完成${gl_bai}"
echo -e "${gl_bai}按任意键继续 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
read -r -n 1 -s -p ""
echo ""
clear
}
install() {
[[ $# -eq 0 ]] && {
log_error "未提供软件包参数!"
return 1
}
local pkg mgr ver installed
local repo_updated=false
for pkg in "$@"; do
installed=false
ver=""
case "$pkg" in
7zip|7z)
command -v 7z &>/dev/null && {
ver=$(7z 2>&1 | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1)
[[ -n "$ver" ]] && installed=true
}
;;
*)
command -v "$pkg" &>/dev/null && {
ver=$("$pkg" --version 2>/dev/null | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1)
[[ -n "$ver" ]] && installed=true
}
;;
esac
if [[ "$installed" == false && -x /usr/bin/opkg ]]; then
opkg list-installed 2>/dev/null | grep -q "^${pkg} " && {
installed=true
ver=$(opkg list-installed 2>/dev/null | awk -v p="$pkg" '$1==p{print $3}')
}
fi
if [[ "$installed" == true ]]; then
echo -e "${gl_huang}${pkg}${gl_bai} ${gl_lv}已安装${gl_bai}${ver:+ 版本 ${gl_lv}${ver}${gl_bai}}"
continue
fi
echo -e "\n${gl_huang}开始安装:${gl_bai}${pkg}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local install_success=false
for mgr in opkg dnf yum apt apk pacman zypper pkg; do
command -v "$mgr" &>/dev/null || continue
case $mgr in
opkg)
echo -e "${gl_bai}使用包管理器: ${gl_zi}opkg (OpenWrt/iStoreOS)${gl_bai}"
[[ $repo_updated == false ]] && opkg update && repo_updated=true
[[ "$pkg" == "7zip" || "$pkg" == "7z" ]] && opkg install p7zip || opkg install "$pkg"
[[ $? -eq 0 ]] && install_success=true
;;
dnf)
echo -e "${gl_bai}使用包管理器: ${gl_zi}dnf (Fedora/RHEL)${gl_bai}"
dnf install -y "$pkg" && install_success=true
;;
yum)
echo -e "${gl_bai}使用包管理器: ${gl_zi}yum (CentOS/RHEL)${gl_bai}"
yum install -y "$pkg" && install_success=true
;;
apt)
echo -e "${gl_bai}使用包管理器: ${gl_zi}apt (Debian/Ubuntu)${gl_bai}"
[[ $repo_updated == false ]] && apt update -y && repo_updated=true
apt install -y "$pkg" && install_success=true
;;
apk)
echo -e "${gl_bai}使用包管理器: ${gl_zi}apk (Alpine)${gl_bai}"
apk add "$pkg" && install_success=true
;;
pacman)
echo -e "${gl_bai}使用包管理器: ${gl_zi}pacman (Arch/Manjaro)${gl_bai}"
pacman -S --noconfirm "$pkg" && install_success=true
;;
zypper)
echo -e "${gl_bai}使用包管理器: ${gl_zi}zypper (openSUSE)${gl_bai}"
zypper install -y "$pkg" && install_success=true
;;
pkg)
echo -e "${gl_bai}使用包管理器: ${gl_zi}pkg (FreeBSD)${gl_bai}"
pkg install -y "$pkg" && install_success=true
;;
esac
[[ "$install_success" == true ]] && break
done
if [[ "$install_success" == true ]]; then
echo -e "${gl_lv}✓ ${pkg} 安装成功${gl_bai}"
else
echo -e "${gl_hong}✗ ${pkg} 安装失败${gl_bai}"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
done
}
get_all_tags() {
local repo="$1"
local auth="$2"
local url="https://hub.docker.com/v2/repositories/${repo}/tags?page_size=100"
local all_tags=""
while [[ -n "$url" && "$url" != "null" ]]; do
local resp http_code
resp=$(curl -s -w "%{http_code}" -u "${auth}" "${url}")
http_code=${resp: -3}
resp=${resp%???}
if [[ "$http_code" != "200" ]]; then
log_error "接口请求失败,HTTP 状态码: ${http_code}"
return 1
fi
if ! echo "$resp" | jq empty 2>/dev/null; then
log_error "接口返回非标准 JSON"
return 1
fi
local page_tags
page_tags=$(echo "$resp" | jq -r '.results[].name')
all_tags+="${page_tags}"$'\n'
url=$(echo "$resp" | jq -r '.next')
done
echo "$all_tags" | sed '/^$/d' | sort -u
}
show_usage() {
clear
echo -e "${gl_zi}>>> Docker Hub 镜像标签查看工具${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}用法:${gl_bai}$0 <用户名:PAT> [仓库1 仓库2 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}]"
echo -e "${gl_bai}示例:"
echo -e " $0 mobufan:dckr_pat_xxxxxx"
echo -e " $0 mobufan:dckr_pat_xxxxxx mobufan/cmdbox mobufan/test"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
}
main() {
install curl jq
local AUTH=""
local REPO_LIST=()
if [[ $# -ge 1 ]]; then
AUTH="$1"
shift
REPO_LIST=("$@")
fi
clear
echo -e "${gl_zi}>>> Docker Hub 镜像标签查看工具${gl_bai}"
echo -e "${gl_bufan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${gl_bai}"
while [[ -z "${AUTH}" ]]; do
read -r -e -p "$(echo -e "${gl_bai}请输入 用户名:PAT (格式:mobufan:dckr_pat_xxxxxx,${gl_hong}0 ${gl_bai}退出): ")" AUTH
[[ "${AUTH}" = "0" ]] && exit_script
done
if [[ ${#REPO_LIST[@]} -eq 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}请输入镜像仓库(多仓库空格分隔,格式:用户名/仓库名,输入 0 退出): ")" REPO_INPUT
[[ "${REPO_INPUT}" = "0" ]] && exit_script
[[ -z "${REPO_INPUT}" ]] && REPO_INPUT="mobufan/cmdbox"
REPO_LIST=($REPO_INPUT)
fi
for repo in "${REPO_LIST[@]}"; do
local USER="${repo%%/*}"
echo -e ""
echo -e "${gl_huang}>>> ${gl_bai}仓库: ${gl_huang}${repo}${gl_bai} (操作用户: ${gl_lv}${USER}${gl_bai})"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}正在获取标签列表 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
local TAGS
TAGS=$(get_all_tags "${repo}" "${AUTH}") || continue
if [[ -z "${TAGS}" ]]; then
log_warn "仓库 ${repo} 暂无标签"
continue
fi
echo -e "${gl_bai}当前标签列表:"
echo -e "${gl_lv}${TAGS}${gl_bai}"
done
echo -e ""
echo -e "${gl_bufan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${gl_bai}"
break_end
}
main "$@"
创建本地脚本
new_script="docker-hub_images_check.sh"
cat > "$new_script" << 'EOF'
#!/bin/bash
set -uo pipefail
IFS=$'\n\t'
list_color_init() {
export gl_hui=$'\033[38;5;59m'
export gl_hong=$'\033[38;5;9m'
export gl_lv=$'\033[38;5;10m'
export gl_huang=$'\033[38;5;11m'
export gl_lan=$'\033[38;5;32m'
export gl_bai=$'\033[38;5;15m'
export gl_zi=$'\033[38;5;13m'
export gl_bufan=$'\033[38;5;14m'
export reset=$'\033[0m'
}
list_color_init
log_info() { echo -e "${gl_lan}[信息]${gl_bai} $*"; }
log_ok() { echo -e "${gl_lv}[成功]${gl_bai} $*"; }
log_warn() { echo -e "${gl_huang}[警告]${gl_bai} $*"; }
log_error() { echo -e "${gl_hong}[错误]${gl_bai} $*" >&2; }
exit_script() {
echo ""
echo -ne "${gl_hong}感谢使用,再见!${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep 0.5
echo -ne "${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
sleep 0.6
clear
exit 0
}
break_end() {
echo -e "${gl_lv}操作完成${gl_bai}"
echo -e "${gl_bai}按任意键继续 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
read -r -n 1 -s -p ""
echo ""
clear
}
install() {
[[ $# -eq 0 ]] && {
log_error "未提供软件包参数!"
return 1
}
local pkg mgr ver installed
local repo_updated=false
for pkg in "$@"; do
installed=false
ver=""
case "$pkg" in
7zip|7z)
command -v 7z &>/dev/null && {
ver=$(7z 2>&1 | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1)
[[ -n "$ver" ]] && installed=true
}
;;
*)
command -v "$pkg" &>/dev/null && {
ver=$("$pkg" --version 2>/dev/null | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1)
[[ -n "$ver" ]] && installed=true
}
;;
esac
if [[ "$installed" == false && -x /usr/bin/opkg ]]; then
opkg list-installed 2>/dev/null | grep -q "^${pkg} " && {
installed=true
ver=$(opkg list-installed 2>/dev/null | awk -v p="$pkg" '$1==p{print $3}')
}
fi
if [[ "$installed" == true ]]; then
echo -e "${gl_huang}${pkg}${gl_bai} ${gl_lv}已安装${gl_bai}${ver:+ 版本 ${gl_lv}${ver}${gl_bai}}"
continue
fi
echo -e "\n${gl_huang}开始安装:${gl_bai}${pkg}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
local install_success=false
for mgr in opkg dnf yum apt apk pacman zypper pkg; do
command -v "$mgr" &>/dev/null || continue
case $mgr in
opkg)
echo -e "${gl_bai}使用包管理器: ${gl_zi}opkg (OpenWrt/iStoreOS)${gl_bai}"
[[ $repo_updated == false ]] && opkg update && repo_updated=true
[[ "$pkg" == "7zip" || "$pkg" == "7z" ]] && opkg install p7zip || opkg install "$pkg"
[[ $? -eq 0 ]] && install_success=true
;;
dnf)
echo -e "${gl_bai}使用包管理器: ${gl_zi}dnf (Fedora/RHEL)${gl_bai}"
dnf install -y "$pkg" && install_success=true
;;
yum)
echo -e "${gl_bai}使用包管理器: ${gl_zi}yum (CentOS/RHEL)${gl_bai}"
yum install -y "$pkg" && install_success=true
;;
apt)
echo -e "${gl_bai}使用包管理器: ${gl_zi}apt (Debian/Ubuntu)${gl_bai}"
[[ $repo_updated == false ]] && apt update -y && repo_updated=true
apt install -y "$pkg" && install_success=true
;;
apk)
echo -e "${gl_bai}使用包管理器: ${gl_zi}apk (Alpine)${gl_bai}"
apk add "$pkg" && install_success=true
;;
pacman)
echo -e "${gl_bai}使用包管理器: ${gl_zi}pacman (Arch/Manjaro)${gl_bai}"
pacman -S --noconfirm "$pkg" && install_success=true
;;
zypper)
echo -e "${gl_bai}使用包管理器: ${gl_zi}zypper (openSUSE)${gl_bai}"
zypper install -y "$pkg" && install_success=true
;;
pkg)
echo -e "${gl_bai}使用包管理器: ${gl_zi}pkg (FreeBSD)${gl_bai}"
pkg install -y "$pkg" && install_success=true
;;
esac
[[ "$install_success" == true ]] && break
done
if [[ "$install_success" == true ]]; then
echo -e "${gl_lv}✓ ${pkg} 安装成功${gl_bai}"
else
echo -e "${gl_hong}✗ ${pkg} 安装失败${gl_bai}"
fi
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
done
}
get_all_tags() {
local repo="$1"
local auth="$2"
local url="https://hub.docker.com/v2/repositories/${repo}/tags?page_size=100"
local all_tags=""
while [[ -n "$url" && "$url" != "null" ]]; do
local resp http_code
resp=$(curl -s -w "%{http_code}" -u "${auth}" "${url}")
http_code=${resp: -3}
resp=${resp%???}
if [[ "$http_code" != "200" ]]; then
log_error "接口请求失败,HTTP 状态码: ${http_code}"
return 1
fi
if ! echo "$resp" | jq empty 2>/dev/null; then
log_error "接口返回非标准 JSON"
return 1
fi
local page_tags
page_tags=$(echo "$resp" | jq -r '.results[].name')
all_tags+="${page_tags}"$'\n'
url=$(echo "$resp" | jq -r '.next')
done
echo "$all_tags" | sed '/^$/d' | sort -u
}
show_usage() {
clear
echo -e "${gl_zi}>>> Docker Hub 镜像标签查看工具${gl_bai}"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}用法:${gl_bai}$0 <用户名:PAT> [仓库1 仓库2 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}]"
echo -e "${gl_bai}示例:"
echo -e " $0 mobufan:dckr_pat_xxxxxx"
echo -e " $0 mobufan:dckr_pat_xxxxxx mobufan/cmdbox mobufan/test"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
}
main() {
install curl jq
local AUTH=""
local REPO_LIST=()
if [[ $# -ge 1 ]]; then
AUTH="$1"
shift
REPO_LIST=("$@")
fi
clear
echo -e "${gl_zi}>>> Docker Hub 镜像标签查看工具${gl_bai}"
echo -e "${gl_bufan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${gl_bai}"
while [[ -z "${AUTH}" ]]; do
read -r -e -p "$(echo -e "${gl_bai}请输入 用户名:PAT (格式:mobufan:dckr_pat_xxxxxx,${gl_hong}0 ${gl_bai}退出): ")" AUTH
[[ "${AUTH}" = "0" ]] && exit_script
done
if [[ ${#REPO_LIST[@]} -eq 0 ]]; then
read -r -e -p "$(echo -e "${gl_bai}请输入镜像仓库(多仓库空格分隔,格式:用户名/仓库名,输入 0 退出): ")" REPO_INPUT
[[ "${REPO_INPUT}" = "0" ]] && exit_script
[[ -z "${REPO_INPUT}" ]] && REPO_INPUT="mobufan/cmdbox"
REPO_LIST=($REPO_INPUT)
fi
for repo in "${REPO_LIST[@]}"; do
local USER="${repo%%/*}"
echo -e ""
echo -e "${gl_huang}>>> ${gl_bai}仓库: ${gl_huang}${repo}${gl_bai} (操作用户: ${gl_lv}${USER}${gl_bai})"
echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
echo -e "${gl_bai}正在获取标签列表 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
local TAGS
TAGS=$(get_all_tags "${repo}" "${AUTH}") || continue
if [[ -z "${TAGS}" ]]; then
log_warn "仓库 ${repo} 暂无标签"
continue
fi
echo -e "${gl_bai}当前标签列表:"
echo -e "${gl_lv}${TAGS}${gl_bai}"
done
echo -e ""
echo -e "${gl_bufan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${gl_bai}"
break_end
}
main "$@"
EOF
chmod +x "$new_script" && ./"$new_script" && rm -f "$new_script"
相关命令
- docker-hub_images_check 👈 当前所在位置
- docker-hub_images_delete
- docker-hub_images_delete_menu
- docker_build_push_img
- docker_check_env
- docker_clean_all
- docker_container_export
- docker_container_import
- docker_daily_scripts
- docker_disk_list
- docker_images_list
- docker_images_manager
- docker_install_uninstall
- docker_login
- docker_login_check
- docker_network_list
- docker_occupy_list
- docker_port_list
- docker_ps_list
- docker_update_all
- docker_user
- docker_volume_list