2021-10-08 00:03:44 +08:00
#!/bin/bash
## Author: SuperManito
2025-10-12 07:22:53 +08:00
## Modified: 2025-10-12
2023-05-02 18:22:44 +08:00
## License: MIT
2023-06-24 11:06:30 +08:00
## GitHub: https://github.com/SuperManito/LinuxMirrors
2023-05-10 19:39:29 +08:00
## Website: https://linuxmirrors.cn
2023-05-05 22:39:34 +08:00
2023-06-24 11:06:30 +08:00
## Docker CE 软件源列表
2023-05-10 19:39:29 +08:00
mirror_list_docker_ce = (
2025-10-12 07:22:53 +08:00
"mirrors.aliyun.com/docker-ce"
"mirrors.tencent.com/docker-ce"
"mirrors.huaweicloud.com/docker-ce"
"mirrors.163.com/docker-ce"
"mirrors.volces.com/docker"
"mirror.azure.cn/docker-ce"
"mirrors.tuna.tsinghua.edu.cn/docker-ce"
"mirrors.pku.edu.cn/docker-ce"
"mirrors.zju.edu.cn/docker-ce"
"mirrors.nju.edu.cn/docker-ce"
"mirror.sjtu.edu.cn/docker-ce"
"mirrors.cqupt.edu.cn/docker-ce"
"mirrors.ustc.edu.cn/docker-ce"
"mirror.iscas.ac.cn/docker-ce"
"download.docker.com"
2023-05-10 19:39:29 +08:00
)
2024-06-07 16:33:26 +08:00
## Docker Registry 仓库列表
2023-05-10 19:39:29 +08:00
mirror_list_registry = (
2025-10-12 07:22:53 +08:00
"docker.1ms.run"
"dockerproxy.net"
"docker.m.daocloud.io"
"docker.1panel.live"
"registry.cn-hangzhou.aliyuncs.com"
"registry.cn-shanghai.aliyuncs.com"
"registry.cn-qingdao.aliyuncs.com"
"registry.cn-beijing.aliyuncs.com"
"registry.cn-zhangjiakou.aliyuncs.com"
"registry.cn-huhehaote.aliyuncs.com"
"registry.cn-wulanchabu.aliyuncs.com"
"registry.cn-shenzhen.aliyuncs.com"
"registry.cn-heyuan.aliyuncs.com"
"registry.cn-guangzhou.aliyuncs.com"
"registry.cn-chengdu.aliyuncs.com"
"registry.cn-hongkong.aliyuncs.com"
"registry.ap-northeast-1.aliyuncs.com"
"registry.ap-southeast-1.aliyuncs.com"
"registry.ap-southeast-3.aliyuncs.com"
"registry.ap-southeast-5.aliyuncs.com"
"registry.eu-central-1.aliyuncs.com"
"registry.eu-west-1.aliyuncs.com"
"registry.us-west-1.aliyuncs.com"
"registry.us-east-1.aliyuncs.com"
"registry.me-east-1.aliyuncs.com"
"mirror.ccs.tencentyun.com"
"gcr.io"
"asia.gcr.io"
"eu.gcr.io"
"registry.hub.docker.com"
2023-05-10 19:39:29 +08:00
)
2021-10-08 00:03:44 +08:00
2025-07-18 23:26:41 +08:00
## 配置需要区分公网地址和内网地址的软件源(不分地域)
# 需要同时在两个数组变量中分别定义软件源地址,并且保证排列顺序一致
# 软件源公网地址列表
mirror_list_extranet = (
"mirrors.aliyun.com/docker-ce"
"mirrors.tencent.com/docker-ce"
"mirrors.huaweicloud.com/docker-ce"
"mirrors.volces.com/docker-ce"
)
# 软件源内网地址列表
mirror_list_intranet = (
"mirrors.cloud.aliyuncs.com/docker-ce"
"mirrors.tencentyun.com/docker-ce"
"mirrors.myhuaweicloud.com/docker-ce"
"mirrors.ivolces.com/docker-ce"
)
2025-05-19 13:43:33 +08:00
## 赞助商广告
SPONSOR_ADS = (
"1Panel · Linux 面板|极简运维 ➜ \033[3mhttps://1panel.cn\033[0m"
"多途云 · 智能化防护,每一次连接皆在安全之下 ➜ \033[3mhttps://www.duotuyun.com\033[0m"
2025-06-10 23:34:26 +08:00
"毫秒镜像 · 专为中国开发者提供Docker镜像加速下载服务 ➜ \033[3mhttps://1ms.run\033[0m"
2025-08-17 19:08:21 +08:00
"不死鸟CDN · 香港日本高防CDN, 免实名/免备案, 轻松阻断DDOS/CC攻击 ➜ \033[3mhttps://www.bsncdn.org\033[0m"
2025-08-20 00:02:34 +08:00
"青叶云 · 香港1T高防| 自助防火墙, 无视CC| 大带宽回国优化线路 ➜ \033[3mhttps://www.qingyeyun.com\033[0m"
2025-09-07 23:12:06 +08:00
"莱卡云 · 专业云计算服务器提供商 ➜ \033[3m https://www.lcayun.com\033[0m"
2025-09-15 10:53:21 +08:00
"云悠YUNYOO · 全球高性价比云服务器| 低至15.99元起 ➜ \033[3mhttps://yunyoo.cc\033[0m"
2025-05-19 13:43:33 +08:00
"速拓云 · 国内高防云28元/月| 香港云100M优化线路9元/月 ➜ \033[3mhttps://www.sutuoyun.com\033[0m"
"林枫云 · 专注独立IP高频VPS| R9/i9系列定制 ➜ \033[3mhttps://www.dkdun.cn\033[0m"
"语鹿云盾 · 专业CDN加速、防御, 亚太百兆三网优化CDN低至9元起 ➜ \033[3mhttps://www.lucdn.cn\033[0m"
2025-06-02 00:55:16 +08:00
"不二云 · 国内外建站快响应服务器的不二之选 ➜ \033[3mhttps://cb2.cn\033[0m"
2025-06-20 01:21:37 +08:00
"HKGserver · 全球家宽| 双ISP| 住宅原生云服务器54元/月起 ➜ \033[3mhttps://www.hkgserver.com\033[0m"
2025-08-29 18:49:51 +08:00
"浪浪云 · BGP网络让每一次连接都纵享丝滑, 明码标价、无套路续费 ➜ \033[3mhttps://langlangy.cn\033[0m"
2025-05-19 13:43:33 +08:00
)
##############################################################################
2021-10-08 00:03:44 +08:00
## 定义系统判定变量
SYSTEM_DEBIAN = "Debian"
SYSTEM_UBUNTU = "Ubuntu"
SYSTEM_KALI = "Kali"
2024-07-25 10:21:28 +08:00
SYSTEM_DEEPIN = "Deepin"
SYSTEM_LINUX_MINT = "Linuxmint"
2024-10-07 08:17:16 +08:00
SYSTEM_ZORIN = "Zorin"
2025-03-15 23:10:49 +08:00
SYSTEM_RASPBERRY_PI_OS = "Raspberry Pi OS"
2021-10-08 00:03:44 +08:00
SYSTEM_REDHAT = "RedHat"
2024-07-25 10:21:28 +08:00
SYSTEM_RHEL = "Red Hat Enterprise Linux"
2021-10-08 00:03:44 +08:00
SYSTEM_CENTOS = "CentOS"
2023-05-01 20:09:10 +08:00
SYSTEM_CENTOS_STREAM = "CentOS Stream"
SYSTEM_ROCKY = "Rocky"
2023-05-10 19:39:29 +08:00
SYSTEM_ALMALINUX = "AlmaLinux"
2021-10-08 00:03:44 +08:00
SYSTEM_FEDORA = "Fedora"
2025-07-18 08:26:53 +08:00
SYSTEM_ORACLE = "Oracle Linux"
2023-05-10 19:39:29 +08:00
SYSTEM_OPENCLOUDOS = "OpenCloudOS"
2025-04-01 23:33:05 +08:00
SYSTEM_OPENCLOUDOS_STREAM = "OpenCloudOS Stream"
2025-08-08 01:44:24 +08:00
SYSTEM_TENCENTOS = "TencentOS"
2023-05-01 20:09:10 +08:00
SYSTEM_OPENEULER = "openEuler"
2024-12-05 06:02:06 +08:00
SYSTEM_ANOLISOS = "Anolis"
2025-04-01 23:33:05 +08:00
SYSTEM_OPENKYLIN = "openKylin"
2024-07-25 10:21:28 +08:00
SYSTEM_OPENSUSE = "openSUSE"
SYSTEM_ARCH = "Arch"
SYSTEM_ALPINE = "Alpine"
2025-04-01 23:33:05 +08:00
SYSTEM_GENTOO = "Gentoo"
SYSTEM_NIXOS = "NixOS"
2021-10-08 00:03:44 +08:00
2024-07-25 10:21:28 +08:00
## 定义系统版本文件
2023-05-01 20:09:10 +08:00
File_LinuxRelease = /etc/os-release
File_RedHatRelease = /etc/redhat-release
2024-07-25 10:21:28 +08:00
File_DebianVersion = /etc/debian_version
File_ArmbianRelease = /etc/armbian-release
2025-03-16 19:30:40 +08:00
File_RaspberryPiOSRelease = /etc/rpi-issue
2023-05-01 20:09:10 +08:00
File_openEulerRelease = /etc/openEuler-release
2025-08-03 09:17:23 +08:00
File_HuaweiCloudEulerOSRelease = /etc/hce-release
2024-12-06 00:13:13 +08:00
File_OpenCloudOSRelease = /etc/opencloudos-release
2025-08-08 01:44:24 +08:00
File_TencentOSServerRelease = /etc/tlinux-release
2024-10-31 02:51:48 +08:00
File_AnolisOSRelease = /etc/anolis-release
2025-08-08 01:44:24 +08:00
File_AlibabaCloudLinuxRelease = /etc/alinux-release
2025-04-01 23:33:05 +08:00
File_OracleLinuxRelease = /etc/oracle-release
2024-07-26 19:05:33 +08:00
File_ArchLinuxRelease = /etc/arch-release
2025-07-04 05:07:37 +08:00
File_ManjaroRelease = /etc/manjaro-release
2024-07-25 10:21:28 +08:00
File_AlpineRelease = /etc/alpine-release
2025-07-04 05:07:37 +08:00
File_GentooRelease = /etc/gentoo-release
File_openKylinVersion = /etc/kylin-version/kylin-system-version.conf
2024-07-25 10:21:28 +08:00
## 定义软件源相关文件或目录
2025-05-13 06:21:27 +08:00
File_AptSourceList = /etc/apt/sources.list
Dir_AptAdditionalSources = /etc/apt/sources.list.d
2023-05-10 19:39:29 +08:00
Dir_YumRepos = /etc/yum.repos.d
2021-10-08 00:03:44 +08:00
## 定义 Docker 相关变量
2025-05-19 04:03:20 +08:00
Dir_Docker = /etc/docker
File_DockerConfig = $Dir_Docker /daemon.json
File_DockerConfigBackup = $Dir_Docker /daemon.json.bak
File_DockerVersionTmp = docker-version.txt
File_DockerCEVersionTmp = docker-ce-version.txt
File_DockerCECliVersionTmp = docker-ce-cli-version.txt
2025-08-08 01:44:24 +08:00
File_DockerSourceList = $Dir_AptAdditionalSources /docker.list
File_DockerRepo = $Dir_YumRepos /docker-ce.repo
2021-10-08 00:03:44 +08:00
2025-05-13 06:21:27 +08:00
## 定义颜色和样式变量
2021-12-15 20:16:53 +08:00
RED = '\033[31m'
GREEN = '\033[32m'
YELLOW = '\033[33m'
BLUE = '\033[34m'
2024-07-25 10:21:28 +08:00
PURPLE = '\033[35m'
AZURE = '\033[36m'
2021-12-15 20:16:53 +08:00
PLAIN = '\033[0m'
BOLD = '\033[1m'
2024-12-06 20:56:39 +08:00
SUCCESS = " \033[1;32m✔ ${ PLAIN } "
COMPLETE = " \033[1;32m✔ ${ PLAIN } "
WARN = " \033[1;43m 警告 ${ PLAIN } "
ERROR = " \033[1;31m✘ ${ PLAIN } "
FAIL = " \033[1;31m✘ ${ PLAIN } "
TIP = " \033[1;44m 提示 ${ PLAIN } "
2025-03-20 23:11:18 +08:00
WORKING = " \033[1;36m◉ ${ PLAIN } "
2024-07-25 10:21:28 +08:00
function main( ) {
permission_judgment
collect_system_info
2024-07-26 19:05:33 +08:00
run_start
2024-07-25 10:21:28 +08:00
choose_mirrors
2025-05-12 04:55:37 +08:00
if [ [ " ${ ONLY_REGISTRY } " = = "true" ] ] ; then
only_change_docker_registry_mirror
else
choose_protocol
close_firewall_service
install_dependency_packages
configure_docker_ce_mirror
install_docker_engine
change_docker_registry_mirror
check_installed_result
fi
2024-07-25 10:21:28 +08:00
run_end
}
2021-12-15 20:16:53 +08:00
2024-07-26 19:05:33 +08:00
function handle_command_options( ) {
## 判断参数
while [ $# -gt 0 ] ; do
case " $1 " in
## 指定 Docker CE 软件源地址
--source)
if [ " $2 " ] ; then
echo " $2 " | grep -Eq "\(|\)|\[|\]|\{|\}"
if [ $? -eq 0 ] ; then
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.validAddress" ) "
2024-07-26 19:05:33 +08:00
else
SOURCE = " $( echo " $2 " | sed -e 's,^http[s]\?://,,g' -e 's,/$,,' ) "
shift
fi
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.sourceAddress" ) "
2024-07-26 19:05:33 +08:00
fi
; ;
## 指定 Docker Registry 仓库地址
--source-registry)
if [ " $2 " ] ; then
echo " $2 " | grep -Eq "\(|\)|\[|\]|\{|\}"
if [ $? -eq 0 ] ; then
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.validAddress" ) "
2024-07-26 19:05:33 +08:00
else
SOURCE_REGISTRY = " $( echo " $2 " | sed -e 's,^http[s]\?://,,g' -e 's,/$,,' ) "
shift
fi
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.registryAddress" ) "
2024-07-26 19:05:33 +08:00
fi
; ;
2025-01-04 19:20:15 +08:00
## 指定 Docker CE 软件源仓库
--branch)
if [ " $2 " ] ; then
SOURCE_BRANCH = " $2 "
shift
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.sourceRepository" ) "
2025-01-04 19:20:15 +08:00
fi
; ;
2025-09-26 20:34:11 +08:00
## 指定 Docker CE 软件源仓库版本
--branch-version)
2024-07-26 19:05:33 +08:00
if [ " $2 " ] ; then
2025-09-26 20:34:11 +08:00
echo " $2 " | grep -Eq " ^[0-9]{1,2} $"
if [ $? -eq 0 ] ; then
SOURCE_BRANCH_VERSION = " $2 "
shift
else
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.validVersion" ) "
2025-09-26 20:34:11 +08:00
fi
2024-07-26 19:05:33 +08:00
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.ceRepositoryVersion" ) "
2024-07-26 19:05:33 +08:00
fi
; ;
2025-01-04 19:20:15 +08:00
## 指定 Docker Engine 安装版本
--designated-version)
if [ " $2 " ] ; then
echo " $2 " | grep -Eq " ^[0-9][0-9].[0-9]{1,2}.[0-9]{1,2} $"
if [ $? -eq 0 ] ; then
DESIGNATED_DOCKER_VERSION = " $2 "
shift
else
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.validVersion" ) "
2025-01-04 19:20:15 +08:00
fi
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.version" ) "
2025-01-04 19:20:15 +08:00
fi
; ;
2025-09-26 20:34:11 +08:00
## 指定 Debian 版本代号
--codename)
if [ " $2 " ] ; then
DEBIAN_CODENAME = " $2 "
shift
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.codename" ) "
2025-09-26 20:34:11 +08:00
fi
; ;
2025-10-12 07:22:53 +08:00
## Web 协议( HTTP/HTTPS)
2025-01-04 19:20:15 +08:00
--protocol)
if [ " $2 " ] ; then
case " $2 " in
http | https | HTTP | HTTPS)
WEB_PROTOCOL = " ${ 2 ,, } "
shift
; ;
*)
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.protocol" ) "
2025-01-04 19:20:15 +08:00
; ;
esac
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.needProtocol" ) "
2025-01-04 19:20:15 +08:00
fi
; ;
2025-07-18 23:26:41 +08:00
## 使用内网地址
--use-intranet-source)
if [ " $2 " ] ; then
case " $2 " in
[ Tt] rue | [ Ff] alse)
USE_INTRANET_SOURCE = " ${ 2 ,, } "
shift
; ;
*)
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.needIntranetSource" ) "
2025-07-18 23:26:41 +08:00
; ;
esac
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.needIntranetSource" ) "
2025-07-18 23:26:41 +08:00
fi
; ;
2024-07-26 19:05:33 +08:00
## 安装最新版本
2024-10-24 12:58:52 +08:00
--install-latest | --install-latested)
2024-07-26 19:05:33 +08:00
if [ " $2 " ] ; then
case " $2 " in
[ Tt] rue | [ Ff] alse)
INSTALL_LATESTED_DOCKER = " ${ 2 ,, } "
shift
; ;
*)
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.needIntranetSource" ) "
2024-07-26 19:05:33 +08:00
; ;
esac
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.needIntranetSource" ) "
2024-07-26 19:05:33 +08:00
fi
; ;
## 忽略覆盖备份提示
--ignore-backup-tips)
IGNORE_BACKUP_TIPS = "true"
; ;
2024-12-06 20:56:39 +08:00
## 关闭防火墙
--close-firewall)
if [ " $2 " ] ; then
case " $2 " in
[ Tt] rue | [ Ff] alse)
CLOSE_FIREWALL = " ${ 2 ,, } "
shift
; ;
*)
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.needIntranetSource" ) "
2024-12-06 20:56:39 +08:00
; ;
esac
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.needIntranetSource" ) "
2024-12-06 20:56:39 +08:00
fi
; ;
2024-12-05 06:02:06 +08:00
## 清除屏幕上的所有内容
--clean-screen)
if [ " $2 " ] ; then
case " $2 " in
[ Tt] rue | [ Ff] alse)
CLEAN_SCREEN = " ${ 2 ,, } "
shift
; ;
*)
2025-10-12 07:22:53 +08:00
command_error " $2 " " $( msg "error.cmd.options.needIntranetSource" ) "
2024-12-05 06:02:06 +08:00
; ;
esac
else
2025-10-12 07:22:53 +08:00
command_error " $1 " " $( msg "error.cmd.options.needIntranetSource" ) "
2024-12-05 06:02:06 +08:00
fi
; ;
2025-10-12 07:22:53 +08:00
## Locale
--lang)
if [ " $2 " ] ; then
local lang_norm = " ${ 2 //_/- } "
lang_norm = " ${ lang_norm ,, } "
case " $lang_norm " in
zh | zh-cn | zh-hans | zh-hans-*)
init_msg_pack "zh-hans"
shift
; ;
zh-hant | zh-hant-* | zh-tw | zh-hk)
init_msg_pack "zh-hant"
shift
; ;
en | en-us | en-*)
init_msg_pack "en"
shift
; ;
auto)
choose_display_language
shift
; ;
*)
command_error " $2 " " $( msg "error.cmd.options.validLangKey" ) "
; ;
esac
else
command_error " $1 " " $( msg "error.cmd.options.langKey" ) "
fi
; ;
--zh | --zh-[ Cc] [ Nn] )
init_msg_pack "zh-hans"
; ;
--en | --en-[ Uu] [ Ss] )
init_msg_pack "en"
; ;
--zh-[ Hh] an[ st] )
init_msg_pack " $1 "
; ;
2025-05-12 04:55:37 +08:00
## 仅更换镜像仓库模式
--only-registry)
ONLY_REGISTRY = "true"
; ;
2025-04-05 17:21:37 +08:00
## 纯净模式
--pure-mode)
PURE_MODE = "true"
; ;
2024-07-26 19:05:33 +08:00
## 命令帮助
--help)
2025-10-12 07:22:53 +08:00
echo -e " \n $( msg "commands.help" "https://github.com/SuperManito/LinuxMirrors/issues" ) \n "
2024-07-26 19:05:33 +08:00
exit
; ;
*)
2025-07-18 08:26:53 +08:00
command_error " $1 "
2024-07-26 19:05:33 +08:00
; ;
esac
shift
done
2025-04-05 17:21:37 +08:00
## 设置部分功能的默认值
2024-07-26 19:05:33 +08:00
IGNORE_BACKUP_TIPS = " ${ IGNORE_BACKUP_TIPS :- "false" } "
2025-01-04 19:20:15 +08:00
if [ [ " ${ DESIGNATED_DOCKER_VERSION } " ] ] ; then
INSTALL_LATESTED_DOCKER = "false"
fi
2025-04-05 17:21:37 +08:00
PURE_MODE = " ${ PURE_MODE :- "false" } "
2024-07-26 19:05:33 +08:00
}
function run_start( ) {
2024-12-05 06:02:06 +08:00
if [ -z " ${ CLEAN_SCREEN } " ] ; then
[ [ -z " ${ SOURCE } " || -z " ${ SOURCE_REGISTRY } " ] ] && clear
elif [ " ${ CLEAN_SCREEN } " = = "true" ] ; then
clear
fi
2025-04-05 17:21:37 +08:00
if [ [ " ${ PURE_MODE } " = = "true" ] ] ; then
return
fi
2025-10-12 07:22:53 +08:00
local system_name = " ${ SYSTEM_PRETTY_NAME :- " ${ SYSTEM_NAME } ${ SYSTEM_VERSION_ID } " } "
local arch = " ${ DEVICE_ARCH } "
local date_time = " $( date "+%Y-%m-%d %H:%M" ) "
local time_zone = " $( timedatectl status 2>/dev/null | grep "Time zone" | awk -F ':' '{print$2}' | awk -F ' ' '{print$1}' ) "
2025-04-05 17:21:37 +08:00
echo -e "+-----------------------------------+"
2024-12-06 20:56:39 +08:00
echo -e "| \033[0;1;35;95m⡇\033[0m \033[0;1;33;93m⠄\033[0m \033[0;1;32;92m⣀⡀\033[0m \033[0;1;36;96m⡀\033[0;1;34;94m⢀\033[0m \033[0;1;35;95m⡀⢀\033[0m \033[0;1;31;91m⡷\033[0;1;33;93m⢾\033[0m \033[0;1;32;92m⠄\033[0m \033[0;1;36;96m⡀⣀\033[0m \033[0;1;34;94m⡀\033[0;1;35;95m⣀\033[0m \033[0;1;31;91m⢀⡀\033[0m \033[0;1;33;93m⡀\033[0;1;32;92m⣀\033[0m \033[0;1;36;96m⢀⣀\033[0m |"
echo -e "| \033[0;1;31;91m⠧\033[0;1;33;93m⠤\033[0m \033[0;1;32;92m⠇\033[0m \033[0;1;36;96m⠇⠸\033[0m \033[0;1;34;94m⠣\033[0;1;35;95m⠼\033[0m \033[0;1;31;91m⠜⠣\033[0m \033[0;1;33;93m⠇\033[0;1;32;92m⠸\033[0m \033[0;1;36;96m⠇\033[0m \033[0;1;34;94m⠏\033[0m \033[0;1;35;95m⠏\033[0m \033[0;1;33;93m⠣⠜\033[0m \033[0;1;32;92m⠏\033[0m \033[0;1;34;94m⠭⠕\033[0m |"
2025-04-05 17:21:37 +08:00
echo -e "+-----------------------------------+"
2025-10-12 07:22:53 +08:00
echo -e " $( msg "start.welcome" ) "
echo -e ''
echo -e " $( msg "start.runtimeEnv" ) ${ BLUE } ${ system_name } ${ arch } ${ PLAIN } "
echo -e " $( msg "start.dateTime" ) ${ BLUE } ${ date_time } ${ time_zone } ${ PLAIN } "
sleep 1 >/dev/null 2>& 1
2024-07-26 19:05:33 +08:00
}
function run_end( ) {
2025-04-05 17:21:37 +08:00
if [ [ " ${ PURE_MODE } " = = "true" ] ] ; then
echo ''
return
fi
2025-10-12 07:22:53 +08:00
echo -e " \n✨ $( msg "end.moreInfo" ) 👉 \033[3mhttps://linuxmirrors.cn\033[0m "
2025-05-19 13:43:33 +08:00
if [ [ " ${# SPONSOR_ADS [@] } " -gt 0 ] ] ; then
2025-10-12 07:22:53 +08:00
echo -e " \n\033[2m $( msg "end.sponsorAds" ) \033[0m "
2025-05-19 13:43:33 +08:00
for ad in " ${ SPONSOR_ADS [@] } " ; do
sleep 0.1
echo -e " \033[2m ${ ad } \033[0m "
done
fi
2025-04-08 02:28:46 +08:00
echo -e "\n\033[3;1mPowered by \033[34mLinuxMirrors\033[0m\n"
2023-05-10 19:39:29 +08:00
}
2024-07-25 10:21:28 +08:00
function output_error( ) {
2023-05-10 19:39:29 +08:00
[ " $1 " ] && echo -e " \n $ERROR $1 \n "
exit 1
}
2025-07-18 08:26:53 +08:00
function command_error( ) {
2025-10-12 07:22:53 +08:00
local tmp_text = " $( msg "error.cmd.options.needConfirm" ) "
2025-07-18 08:26:53 +08:00
if [ [ " ${ 2 } " ] ] ; then
2025-10-12 07:22:53 +08:00
tmp_text = " $( msg "error.cmd.options.needSpecify" " ${ 2 } " ) "
2025-07-18 08:26:53 +08:00
fi
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.cmd.options.invalid" " ${ BLUE } $1 ${ PLAIN } " " ${ tmp_text } " ) "
2025-07-18 08:26:53 +08:00
}
function unsupport_system_error( ) {
if [ [ " ${ 2 } " ] ] ; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.unsupportSystem2" " ${ 1 } " ) \n\n ${ BLUE } $2 ${ PLAIN } "
else
output_error " $( msg "error.unsupportSystem1" " ${ 1 } " ) "
2025-07-18 08:26:53 +08:00
fi
}
function input_error( ) {
2025-10-12 07:22:53 +08:00
echo -e " \n $WARN $( msg "error.input" " ${ 1 } " ) "
2025-07-18 08:26:53 +08:00
}
2025-07-02 12:51:05 +08:00
function command_exists( ) {
2025-07-04 05:07:37 +08:00
command -v " $@ " & >/dev/null
2025-07-02 12:51:05 +08:00
}
2024-07-25 10:21:28 +08:00
function permission_judgment( ) {
2023-05-10 19:39:29 +08:00
if [ $UID -ne 0 ] ; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.needRoot" ) "
2023-05-10 19:39:29 +08:00
fi
}
2025-09-04 15:03:31 +08:00
function get_os_release_value( ) {
grep -E " ^ ${ 1 } = " $File_LinuxRelease | cut -d= -f2- | sed "s/[\'\"]//g"
}
2024-07-25 10:21:28 +08:00
function collect_system_info( ) {
2025-09-13 05:36:07 +08:00
if [ ! -s " ${ File_LinuxRelease } " ] ; then
2025-10-12 07:22:53 +08:00
unsupport_system_error " $( msg "error.unknownSystem" ) "
2025-09-13 05:36:07 +08:00
fi
2023-05-01 20:09:10 +08:00
## 定义系统名称
2025-09-04 15:03:31 +08:00
SYSTEM_NAME = " $( get_os_release_value NAME) "
SYSTEM_PRETTY_NAME = " $( get_os_release_value PRETTY_NAME) "
2023-05-01 20:09:10 +08:00
## 定义系统版本号
2025-09-04 15:03:31 +08:00
SYSTEM_VERSION_ID = " $( get_os_release_value VERSION_ID) "
2025-04-01 23:33:05 +08:00
SYSTEM_VERSION_ID_MAJOR = " ${ SYSTEM_VERSION_ID %.* } "
SYSTEM_VERSION_ID_MINOR = " ${ SYSTEM_VERSION_ID #*. } "
2023-05-01 20:09:10 +08:00
## 定义系统ID
2025-09-04 15:03:31 +08:00
SYSTEM_ID = " $( get_os_release_value ID) "
2024-01-18 12:15:13 +08:00
## 判定当前系统派系
2025-03-16 19:30:40 +08:00
if [ -s " ${ File_DebianVersion } " ] ; then
2023-05-01 20:09:10 +08:00
SYSTEM_FACTIONS = " ${ SYSTEM_DEBIAN } "
2025-03-16 19:30:40 +08:00
elif [ -s " ${ File_RedHatRelease } " ] ; then
2024-07-26 19:05:33 +08:00
SYSTEM_FACTIONS = " ${ SYSTEM_REDHAT } "
2025-08-03 09:17:23 +08:00
elif [ -s " ${ File_openEulerRelease } " ] || [ -s " ${ File_HuaweiCloudEulerOSRelease } " ] ; then
2024-12-06 00:13:13 +08:00
SYSTEM_FACTIONS = " ${ SYSTEM_OPENEULER } "
2025-03-16 19:30:40 +08:00
elif [ -s " ${ File_OpenCloudOSRelease } " ] ; then
2024-12-05 06:02:06 +08:00
SYSTEM_FACTIONS = " ${ SYSTEM_OPENCLOUDOS } " # 自 9.0 版本起不再基于红帽
2025-03-16 19:30:40 +08:00
elif [ -s " ${ File_AnolisOSRelease } " ] ; then
2024-12-05 06:02:06 +08:00
SYSTEM_FACTIONS = " ${ SYSTEM_ANOLISOS } " # 自 8.8 版本起不再基于红帽
2025-08-08 01:44:24 +08:00
elif [ -s " ${ File_TencentOSServerRelease } " ] ; then
SYSTEM_FACTIONS = " ${ SYSTEM_TENCENTOS } " # 自 4 版本起不再基于红帽
2025-07-04 05:07:37 +08:00
elif [ -s " ${ File_openKylinVersion } " ] ; then
2025-07-18 08:26:53 +08:00
[ [ " ${ ONLY_REGISTRY } " != "true" ] ] && unsupport_system_error "openKylin" "apt-get install -y docker\nsystemctl enable --now docker"
2025-07-04 05:07:37 +08:00
elif [ -f " ${ File_ArchLinuxRelease } " ] ; then
2025-07-18 08:26:53 +08:00
[ [ " ${ ONLY_REGISTRY } " != "true" ] ] && unsupport_system_error "Arch Linux" "pacman -S docker\nsystemctl enable --now docker"
2025-07-04 05:07:37 +08:00
elif [ -f " ${ File_GentooRelease } " ] ; then
2025-07-18 08:26:53 +08:00
[ [ " ${ ONLY_REGISTRY } " != "true" ] ] && unsupport_system_error "Gentoo"
2025-07-04 05:07:37 +08:00
elif [ [ " ${ SYSTEM_NAME } " = = *"openSUSE" * ] ] ; then
2025-07-18 08:26:53 +08:00
[ [ " ${ ONLY_REGISTRY } " != "true" ] ] && unsupport_system_error "openSUSE" "zypper install docker\nsystemctl enable --now docker"
2025-07-04 05:07:37 +08:00
elif [ [ " ${ SYSTEM_NAME } " = = *"NixOS" * ] ] ; then
2025-07-18 08:26:53 +08:00
[ [ " ${ ONLY_REGISTRY } " != "true" ] ] && unsupport_system_error "NixOS"
2021-10-17 09:09:00 +08:00
else
2025-10-12 07:22:53 +08:00
unsupport_system_error " $( msg "error.unknownSystem" ) "
2021-10-08 00:03:44 +08:00
fi
2024-07-26 19:05:33 +08:00
## 判定系统类型、版本、版本号
2023-05-01 20:09:10 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2025-09-04 15:03:31 +08:00
if command_exists lsb_release; then
SYSTEM_JUDGMENT = " $( lsb_release -is) "
SYSTEM_VERSION_CODENAME = " ${ DEBIAN_CODENAME :- " $( lsb_release -cs) " } "
else
## https://codeberg.org/gioele/lsb-release-minimal
SYSTEM_JUDGMENT = " ${ SYSTEM_ID ^ } "
if [ " ${ SYSTEM_NAME } " ] ; then
if [ [ " ${ SYSTEM_ID ,, } " = = " ${ SYSTEM_NAME ,, } " ] ] ; then
SYSTEM_JUDGMENT = " ${ SYSTEM_NAME } "
fi
2023-05-10 19:39:29 +08:00
fi
2025-09-04 15:03:31 +08:00
SYSTEM_VERSION_CODENAME = " ${ DEBIAN_CODENAME :- " $( get_os_release_value VERSION_CODENAME) " } "
2023-05-10 19:39:29 +08:00
fi
2025-03-15 23:10:49 +08:00
# Raspberry Pi OS
2025-03-16 19:30:40 +08:00
if [ -s " ${ File_RaspberryPiOSRelease } " ] ; then
2025-03-15 23:10:49 +08:00
SYSTEM_JUDGMENT = " ${ SYSTEM_RASPBERRY_PI_OS } "
SYSTEM_PRETTY_NAME = " ${ SYSTEM_RASPBERRY_PI_OS } "
fi
2023-05-01 20:09:10 +08:00
; ;
" ${ SYSTEM_REDHAT } " )
2024-07-25 10:21:28 +08:00
SYSTEM_JUDGMENT = " $( awk '{printf $1}' $File_RedHatRelease ) "
2024-07-26 19:05:33 +08:00
## 特殊系统判断
# Red Hat Enterprise Linux
2024-07-25 10:21:28 +08:00
grep -q " ${ SYSTEM_RHEL } " $File_RedHatRelease && SYSTEM_JUDGMENT = " ${ SYSTEM_RHEL } "
2024-07-26 19:05:33 +08:00
# CentOS Stream
2024-07-25 10:21:28 +08:00
grep -q " ${ SYSTEM_CENTOS_STREAM } " $File_RedHatRelease && SYSTEM_JUDGMENT = " ${ SYSTEM_CENTOS_STREAM } "
2025-07-18 08:26:53 +08:00
# Oracle Linux
[ -s " ${ File_OracleLinuxRelease } " ] && SYSTEM_JUDGMENT = " ${ SYSTEM_ORACLE } "
2023-05-01 20:09:10 +08:00
; ;
2024-07-25 10:21:28 +08:00
*)
SYSTEM_JUDGMENT = " ${ SYSTEM_FACTIONS } "
2021-10-08 00:03:44 +08:00
; ;
esac
## 判定系统处理器架构
2025-03-15 23:10:49 +08:00
DEVICE_ARCH_RAW = " $( uname -m) "
case " ${ DEVICE_ARCH_RAW } " in
2021-10-08 00:03:44 +08:00
x86_64)
2024-07-25 10:21:28 +08:00
DEVICE_ARCH = "x86_64"
2021-10-08 00:03:44 +08:00
; ;
aarch64)
2024-07-25 10:21:28 +08:00
DEVICE_ARCH = "ARM64"
2025-03-15 23:10:49 +08:00
; ;
armv8l)
DEVICE_ARCH = "ARMv8_32"
2021-10-08 00:03:44 +08:00
; ;
armv7l)
2024-07-25 10:21:28 +08:00
DEVICE_ARCH = "ARMv7"
2021-10-08 00:03:44 +08:00
; ;
armv6l)
2024-07-25 10:21:28 +08:00
DEVICE_ARCH = "ARMv6"
2025-03-15 23:10:49 +08:00
; ;
armv5tel)
DEVICE_ARCH = "ARMv5"
2021-10-08 00:03:44 +08:00
; ;
2024-07-26 19:05:33 +08:00
ppc64le)
DEVICE_ARCH = "ppc64le"
; ;
s390x)
DEVICE_ARCH = "s390x"
; ;
2021-12-15 20:16:53 +08:00
i386 | i686)
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.unsupportX86_32" ) "
2021-10-08 00:03:44 +08:00
; ;
*)
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.unknownArch" " ${ DEVICE_ARCH_RAW } " ) "
2021-10-08 00:03:44 +08:00
; ;
esac
2024-12-13 21:50:49 +08:00
## 定义软件源仓库名称
2025-01-04 19:20:15 +08:00
if [ [ -z " ${ SOURCE_BRANCH } " ] ] ; then
case " ${ SYSTEM_FACTIONS } " in
2024-07-26 19:05:33 +08:00
" ${ SYSTEM_DEBIAN } " )
2025-01-04 19:20:15 +08:00
case " ${ SYSTEM_JUDGMENT } " in
" ${ SYSTEM_DEBIAN } " )
SOURCE_BRANCH = "debian"
; ;
" ${ SYSTEM_UBUNTU } " | " ${ SYSTEM_ZORIN } " )
SOURCE_BRANCH = "ubuntu"
; ;
2025-03-15 23:10:49 +08:00
" ${ SYSTEM_RASPBERRY_PI_OS } " )
case " ${ DEVICE_ARCH_RAW } " in
x86_64 | aarch64)
SOURCE_BRANCH = "debian"
; ;
*)
SOURCE_BRANCH = "raspbian"
; ;
esac
; ;
2025-01-04 19:20:15 +08:00
*)
# 部分 Debian 系衍生操作系统使用 Debian 12 的 docker ce 源
SOURCE_BRANCH = "debian"
SYSTEM_VERSION_CODENAME = "bookworm"
; ;
esac
2024-07-26 19:05:33 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-01-04 19:20:15 +08:00
case " ${ SYSTEM_JUDGMENT } " in
" ${ SYSTEM_FEDORA } " )
SOURCE_BRANCH = "fedora"
; ;
" ${ SYSTEM_RHEL } " )
SOURCE_BRANCH = "rhel"
2025-07-18 08:26:53 +08:00
# RHEL 10
2025-06-15 20:20:04 +08:00
if [ [ " ${ SYSTEM_VERSION_ID_MAJOR } " = = 10 ] ] ; then
2025-10-12 07:22:53 +08:00
echo -e " \n $WARN $( msg "warn.usedCentosBranch" ) "
echo -e " \n $TIP $( msg "tip.unsupportRHEL10" ) "
2025-07-18 08:26:53 +08:00
SOURCE_BRANCH = "centos"
2025-06-15 20:20:04 +08:00
fi
2025-01-04 19:20:15 +08:00
; ;
*)
SOURCE_BRANCH = "centos"
; ;
esac
2025-07-04 05:07:37 +08:00
if [ [ " ${ DEVICE_ARCH_RAW } " = = "s390x" ] ] ; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.unsupportS390x" ) "
2025-07-04 05:07:37 +08:00
fi
2024-07-26 19:05:33 +08:00
; ;
esac
2025-01-04 19:20:15 +08:00
fi
2024-01-18 12:15:13 +08:00
## 定义软件源更新文字
2023-05-01 20:09:10 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2025-10-12 07:22:53 +08:00
SYNC_MIRROR_TEXT = " $( msg "source.sync.text1" ) "
2021-10-08 00:03:44 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-10-12 07:22:53 +08:00
SYNC_MIRROR_TEXT = " $( msg "source.sync.text2" ) "
2021-10-08 00:03:44 +08:00
; ;
esac
2024-12-06 00:13:13 +08:00
## 判断是否可以使用高级交互式选择器
CAN_USE_ADVANCED_INTERACTIVE_SELECTION = "false"
2025-07-02 12:51:05 +08:00
if command_exists tput; then
2024-12-06 00:13:13 +08:00
CAN_USE_ADVANCED_INTERACTIVE_SELECTION = "true"
fi
2021-10-08 00:03:44 +08:00
}
2025-10-12 07:22:53 +08:00
## 选择显示语言
function choose_display_language( ) {
local result
if command_exists tput; then
local lang_key_labels = ( )
local language_text
for ( ( i = 0; i < ${# MESSAGE_LANG_KEYS [@] } ; i++) ) ; do
language_text = " ${ MESSAGE_LANG_DISPLAY [ ${ MESSAGE_LANG_KEYS [ $i ] } ] } "
if [ [ " ${ language_text } " ] ] ; then
lang_key_labels += ( " ${ language_text } " )
else
lang_key_labels += ( "" )
fi
done
interactive_select_list "MESSAGE_LANG_KEYS" " \n ${ BOLD } Please select the display language: ${ PLAIN } \n " "lang_key_labels"
result = " ${ _SELECT_RESULT %%@@* } "
else
echo ''
for ( ( i = 0; i < ${# MESSAGE_LANG_KEYS [@] } ; i++) ) ; do
echo -e " $(( i + 1 )) . ${ MESSAGE_LANG_DISPLAY [ ${ MESSAGE_LANG_KEYS [ $i ] } ] } "
done
local CHOICE = " $( echo -e " \n ${ BOLD } └─ Please select and enter the display language [ 1- ${# MESSAGE_LANG_KEYS [@] } ]: ${ PLAIN } " ) "
while true; do
read -rp " ${ CHOICE } " INPUT
case " ${ INPUT } " in
[ 1-9] | [ 1-9] [ 0-9] )
local tmp_result = " ${ MESSAGE_LANG_KEYS [ $(( INPUT - 1 )) ] } "
if [ [ -z " ${ tmp_result } " ] ] ; then
echo -e " \n $WARN $( msg "warn.needValidNumberIndex" ) "
else
result = " ${ tmp_result } "
break
fi
; ;
*)
echo -e " \n $WARN $( msg "warn.needInputNumberIndex" ) "
; ;
esac
done
fi
init_msg_pack " ${ result } "
}
2024-07-25 10:21:28 +08:00
function choose_mirrors( ) {
2023-05-10 19:39:29 +08:00
## 打印软件源列表
2024-07-25 10:21:28 +08:00
function print_mirrors_list( ) {
2025-10-09 02:58:24 +08:00
local tmp_name tmp_index i j
2023-05-10 19:39:29 +08:00
function StringLength( ) {
local text = $1
echo " ${# text } "
}
local list_arr = ( )
local list_arr_sum = " $( eval echo \$ { #$1[@]})"
2025-10-09 02:58:24 +08:00
for ( ( i = 0; i < $list_arr_sum ; i++) ) ; do
list_arr[ $i ] = " $( eval echo \$ { $1 [ i] } ) "
2023-05-10 19:39:29 +08:00
done
2025-10-09 02:58:24 +08:00
local name_width = ${ 2 :- "30" }
2025-10-12 07:22:53 +08:00
local list_labels = ( )
if [ [ " ${ 3 } " ] ] ; then
eval " list_labels=(\"\${ ${ 3 } [@]}\") "
fi
2025-07-02 12:51:05 +08:00
if command_exists printf; then
2025-10-09 02:58:24 +08:00
local tmp_uchar_1 tmp_uchar_2 tmp_uchar_3 tmp_uchar_4 tmp_default_length tmp_length tmp_unicode_length tmp_spaces_nums tmp_max_length
2023-05-10 19:39:29 +08:00
for ( ( i = 0; i < ${# list_arr [@] } ; i++) ) ; do
2025-10-12 07:22:53 +08:00
if [ [ " ${ list_labels [ $i ] } " ] ] ; then
tmp_name = " ${ list_labels [ $i ] } "
else
tmp_name = " ${ list_arr [i] } "
fi
2025-10-09 02:58:24 +08:00
tmp_index = $(( i + 1 ))
tmp_default_length = " ${ name_width } "
tmp_uchar_1 = $( echo " ${ tmp_name } " | grep -c "“" )
tmp_uchar_2 = $( echo " ${ tmp_name } " | grep -c "”" )
tmp_uchar_3 = $( echo " ${ tmp_name } " | grep -c "‘ " )
tmp_uchar_4 = $( echo " ${ tmp_name } " | grep -c "’ " )
[ [ " ${ tmp_uchar_1 } " -gt 0 ] ] && ( ( tmp_default_length += tmp_uchar_1) )
[ [ " ${ tmp_uchar_2 } " -gt 0 ] ] && ( ( tmp_default_length += tmp_uchar_2) )
[ [ " ${ tmp_uchar_3 } " -gt 0 ] ] && ( ( tmp_default_length += tmp_uchar_3) )
[ [ " ${ tmp_uchar_4 } " -gt 0 ] ] && ( ( tmp_default_length += tmp_uchar_4) )
tmp_length = $( StringLength " ${ tmp_name } " )
tmp_unicode_length = $( StringLength " $( echo " ${ tmp_name } " | sed "s|[0-9a-zA-Z -~]||g; s| ||g" ) " )
tmp_max_length = $(( tmp_default_length + tmp_unicode_length))
tmp_spaces_nums = $(( ( ( tmp_default_length - tmp_unicode_length - tmp_length)) / 2) )
if [ [ $tmp_spaces_nums -gt 0 ] ] ; then
tmp_name = " ${ tmp_name } $( printf '%*s' ${ tmp_spaces_nums } '' ) "
fi
printf " ❖ %- ${ tmp_max_length } s %4s\n " " ${ tmp_name } " " ${ tmp_index } ) "
2023-05-10 19:39:29 +08:00
done
else
for ( ( i = 0; i < ${# list_arr [@] } ; i++) ) ; do
2025-10-12 07:22:53 +08:00
if [ [ " ${ list_labels [ $i ] } " ] ] ; then
tmp_name = " ${ list_labels [ $i ] } "
else
tmp_name = " ${ list_arr [i] } "
fi
2025-10-09 02:58:24 +08:00
tmp_index = $(( i + 1 ))
echo -e " ❖ $tmp_index . ${ tmp_name } "
2023-05-10 19:39:29 +08:00
done
fi
}
2025-07-18 23:26:41 +08:00
## 选择使用软件源内网地址
function choose_use_intranet_address( ) {
local intranet_source
for ( ( i = 0; i < ${# mirror_list_extranet [@] } ; i++) ) ; do
if [ [ " ${ SOURCE } " = = " ${ mirror_list_extranet [i] } " ] ] ; then
intranet_source = " ${ mirror_list_intranet [i] } "
break
else
continue
fi
done
if [ [ -z " ${ USE_INTRANET_SOURCE } " ] ] ; then
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
echo ''
2025-10-12 07:22:53 +08:00
interactive_select_boolean " ${ BOLD } $( msg "interaction.source.type.select" ) ${ PLAIN } " " $( msg "interaction.source.type.public" ) " " $( msg "interaction.source.type.intranet" ) "
2025-07-18 23:26:41 +08:00
if [ [ " ${ _SELECT_RESULT } " = = "false" ] ] ; then
SOURCE = " ${ intranet_source } "
2025-09-28 21:38:13 +08:00
ONLY_HTTP = "true" # 强制使用 HTTP 协议
2025-10-12 07:22:53 +08:00
[ [ " ${ PURE_MODE } " != "true" ] ] && echo -e " \n $WARN $( msg "warn.usedIntranetSource" ) "
2025-07-18 23:26:41 +08:00
fi
else
2025-10-12 07:22:53 +08:00
local CHOICE = " $( echo -e " \n ${ BOLD } └─ $( msg "interaction.source.type.usePublicAddress" ) ? [Y/n] ${ PLAIN } " ) "
2025-07-18 23:26:41 +08:00
read -rp " ${ CHOICE } " INPUT
[ [ -z " ${ INPUT } " ] ] && INPUT = Y
case " ${ INPUT } " in
[ Yy] | [ Yy] [ Ee] [ Ss] ) ; ;
[ Nn] | [ Nn] [ Oo] )
SOURCE = " ${ intranet_source } "
2025-09-28 21:38:13 +08:00
ONLY_HTTP = "true" # 强制使用 HTTP 协议
2025-10-12 07:22:53 +08:00
[ [ " ${ PURE_MODE } " != "true" ] ] && echo -e " \n $WARN $( msg "warn.usedIntranetSource" ) "
2025-07-18 23:26:41 +08:00
; ;
*)
2025-10-12 07:22:53 +08:00
input_error " $( msg "error.defaultBehavior.noUseIntranetSource" ) "
2025-07-18 23:26:41 +08:00
; ;
esac
fi
elif [ [ " ${ USE_INTRANET_SOURCE } " = = "true" ] ] ; then
SOURCE = " ${ intranet_source } "
fi
}
2025-10-12 07:22:53 +08:00
local mirror_list_name mirror_list_length
local mirror_list_labels = ( )
local label_msg_index label_msg_content
2025-05-12 04:55:37 +08:00
if [ [ -z " ${ SOURCE } " ] ] && [ [ " ${ ONLY_REGISTRY } " != "true" ] ] ; then
2024-12-06 00:13:13 +08:00
mirror_list_name = "mirror_list_docker_ce"
2025-10-12 07:22:53 +08:00
mirror_list_length = $( eval " echo \${# ${ mirror_list_name } [@]} " )
for ( ( i = 0; i < ${ mirror_list_length } ; i++) ) ; do
label_msg_index = " mirrors.dockerCE. ${ i } "
label_msg_content = " $( msg " ${ label_msg_index } " ) "
if [ [ " ${ label_msg_content } " = = " ${ label_msg_index } " ] ] ; then
mirror_list_labels += ( "" )
else
mirror_list_labels += ( " ${ label_msg_content } " )
fi
done
2024-12-06 00:13:13 +08:00
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
2025-10-12 07:22:53 +08:00
interactive_select_list " ${ mirror_list_name } " " \n ${ BOLD } $( msg "interaction.source.dockerCE.select" ) ${ PLAIN } \n " "mirror_list_labels"
SOURCE = " ${ _SELECT_RESULT %%@@* } "
echo -e " \n ${ GREEN } ➜ ${ PLAIN } ${ BOLD } Docker CE: ${ _SELECT_RESULT #*@@ } ${ PLAIN } "
2024-12-06 00:13:13 +08:00
else
2025-10-09 02:58:24 +08:00
echo ''
2025-10-12 07:22:53 +08:00
print_mirrors_list " ${ mirror_list_name } " 39 "mirror_list_labels"
local CHOICE_B = " $( echo -e " \n ${ BOLD } └─ $( msg "interaction.source.dockerCE.selectAndInput" ) [ 1- $( eval echo \$ { #${mirror_list_name}[@]}) ]: ${PLAIN}")"
2024-12-06 00:13:13 +08:00
while true; do
2025-10-09 02:58:24 +08:00
read -rp " ${ CHOICE_B } " INPUT
2024-12-06 00:13:13 +08:00
case " ${ INPUT } " in
[ 1-9] | [ 1-9] [ 0-9] | [ 1-9] [ 0-9] [ 0-9] )
2025-10-12 07:22:53 +08:00
local tmp_result = " $( eval echo \$ { ${ mirror_list_name } [ $(( INPUT - 1 )) ] } ) "
if [ [ -z " ${ tmp_result } " ] ] ; then
echo -e " \n $WARN $( msg "warn.needValidNumberIndex" ) "
2024-12-06 00:13:13 +08:00
else
2025-10-12 07:22:53 +08:00
SOURCE = " $( echo " ${ tmp_result } " | awk -F '@' '{print$2}' ) "
2024-12-06 00:13:13 +08:00
break
fi
; ;
*)
2025-10-12 07:22:53 +08:00
echo -e " \n $WARN $( msg "warn.needInputNumberIndex" ) "
2024-12-06 00:13:13 +08:00
; ;
esac
done
fi
2023-05-10 19:39:29 +08:00
fi
2025-07-18 23:26:41 +08:00
## 选择软件源内网地址
if [ [ " ${ mirror_list_extranet [*] } " = ~ ( ^| [ ^[ :alpha:] ] ) " ${ SOURCE } " ( [ ^[ :alpha:] ] | $) ] ] ; then
choose_use_intranet_address
fi
2023-05-10 19:39:29 +08:00
if [ [ -z " ${ SOURCE_REGISTRY } " ] ] ; then
mirror_list_name = "mirror_list_registry"
2025-10-12 07:22:53 +08:00
mirror_list_labels = ( )
mirror_list_length = $( eval " echo \${# ${ mirror_list_name } [@]} " )
for ( ( i = 0; i < ${ mirror_list_length } ; i++) ) ; do
label_msg_index = " mirrors.registry. ${ i } "
label_msg_content = " $( msg " ${ label_msg_index } " ) "
if [ [ " ${ label_msg_content } " = = " ${ label_msg_index } " ] ] ; then
mirror_list_labels += ( "" )
else
mirror_list_labels += ( " ${ label_msg_content } " )
fi
done
2024-12-06 00:13:13 +08:00
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
2024-12-06 21:06:23 +08:00
sleep 1 >/dev/null 2>& 1
2025-10-12 07:22:53 +08:00
interactive_select_list " ${ mirror_list_name } " " \n ${ BOLD } $( msg "interaction.source.dockerRegistry.select" ) ${ PLAIN } \n " "mirror_list_labels"
SOURCE_REGISTRY = " ${ _SELECT_RESULT %%@@* } "
echo -e " \n ${ GREEN } ➜ ${ PLAIN } ${ BOLD } Docker Registry: $( echo " ${ _SELECT_RESULT #*@@ } " | sed 's|(推荐)||g; s|(推薦)||g' ) ${ PLAIN } "
2024-12-06 00:13:13 +08:00
else
2025-10-09 02:58:24 +08:00
echo ''
2025-10-12 07:22:53 +08:00
print_mirrors_list " ${ mirror_list_name } " 45 "mirror_list_labels"
local CHOICE_C = " $( echo -e " \n ${ BOLD } └─ $( msg "interaction.source.dockerRegistry.selectAndInput" ) [ 1- $( eval echo \$ { #${mirror_list_name}[@]}) ]: ${PLAIN}")"
2024-12-06 00:13:13 +08:00
while true; do
2025-10-09 02:58:24 +08:00
read -rp " ${ CHOICE_C } " INPUT
2024-12-06 00:13:13 +08:00
case " ${ INPUT } " in
[ 1-9] | [ 1-9] [ 0-9] | [ 1-9] [ 0-9] [ 0-9] )
local tmp_source = " $( eval echo \$ { ${ mirror_list_name } [ $(( $INPUT - 1 )) ] } ) "
if [ [ -z " ${ tmp_source } " ] ] ; then
2025-10-12 07:22:53 +08:00
echo -e " \n $WARN $( msg "warn.needValidNumberIndex" ) "
2024-12-06 00:13:13 +08:00
else
SOURCE_REGISTRY = " $( eval echo \$ { ${ mirror_list_name } [ $(( $INPUT - 1 )) ] } | awk -F '@' '{print$2}' ) "
break
fi
; ;
*)
2025-10-12 07:22:53 +08:00
echo -e " \n $WARN $( msg "warn.needInputNumberIndex" ) "
2024-12-06 00:13:13 +08:00
; ;
esac
done
fi
2023-05-10 19:39:29 +08:00
fi
}
2025-10-12 07:22:53 +08:00
## 选择同步或更新软件源所使用的 Web 协议( HTTP/HTTPS)
2025-01-04 19:20:15 +08:00
function choose_protocol( ) {
if [ [ -z " ${ WEB_PROTOCOL } " ] ] ; then
if [ [ " ${ ONLY_HTTP } " = = "true" ] ] ; then
WEB_PROTOCOL = "http"
else
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
echo ''
2025-10-12 07:22:53 +08:00
interactive_select_boolean " ${ BOLD } $( msg "interaction.protocol.select" ) ${ PLAIN } " "HTTP" "HTTPS"
2025-01-04 19:20:15 +08:00
if [ [ " ${ _SELECT_RESULT } " = = "true" ] ] ; then
WEB_PROTOCOL = "http"
else
WEB_PROTOCOL = "https"
fi
else
2025-10-12 07:22:53 +08:00
local CHOICE = " $( echo -e " \n ${ BOLD } └─ $( msg "interaction.protocol.useHttp" ) ? [Y/n] ${ PLAIN } " ) "
2025-01-04 19:20:15 +08:00
read -rp " ${ CHOICE } " INPUT
[ [ -z " ${ INPUT } " ] ] && INPUT = Y
case " ${ INPUT } " in
[ Yy] | [ Yy] [ Ee] [ Ss] )
WEB_PROTOCOL = "http"
; ;
[ Nn] | [ Nn] [ Oo] )
WEB_PROTOCOL = "https"
; ;
*)
2025-10-12 07:22:53 +08:00
input_error " $( msg "error.defaultBehavior.https" ) "
2025-01-04 19:20:15 +08:00
WEB_PROTOCOL = "https"
; ;
esac
fi
fi
fi
WEB_PROTOCOL = " ${ WEB_PROTOCOL ,, } "
}
2023-05-10 19:39:29 +08:00
## 关闭防火墙和SELinux
2024-07-25 10:21:28 +08:00
function close_firewall_service( ) {
2025-07-02 12:51:05 +08:00
if ! command_exists systemctl; then
2024-01-18 12:15:13 +08:00
return
fi
if [ [ " $( systemctl is-active firewalld) " = = "active" ] ] ; then
if [ [ -z " ${ CLOSE_FIREWALL } " ] ] ; then
2025-10-12 07:22:53 +08:00
local ask_text = " $( msg "interaction.firewall.close" ) ? "
2024-12-06 00:13:13 +08:00
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
echo ''
2025-07-18 08:26:53 +08:00
interactive_select_boolean " ${ BOLD } ${ ask_text } ${ PLAIN } "
2024-12-06 00:13:13 +08:00
if [ [ " ${ _SELECT_RESULT } " = = "true" ] ] ; then
CLOSE_FIREWALL = "true"
fi
else
2025-07-18 08:26:53 +08:00
local CHOICE = " $( echo -e " \n ${ BOLD } └─ ${ ask_text } [Y/n] ${ PLAIN } " ) "
2024-12-06 00:13:13 +08:00
read -rp " ${ CHOICE } " INPUT
[ [ -z " ${ INPUT } " ] ] && INPUT = Y
case " ${ INPUT } " in
[ Yy] | [ Yy] [ Ee] [ Ss] )
CLOSE_FIREWALL = "true"
; ;
[ Nn] | [ Nn] [ Oo] ) ; ;
*)
2025-10-12 07:22:53 +08:00
input_error " $( msg "error.defaultBehavior.noClose" ) "
2024-12-06 00:13:13 +08:00
; ;
esac
fi
2024-01-18 12:15:13 +08:00
fi
if [ [ " ${ CLOSE_FIREWALL } " = = "true" ] ] ; then
local SelinuxConfig = /etc/selinux/config
systemctl disable --now firewalld >/dev/null 2>& 1
2025-03-16 19:30:40 +08:00
[ -s " ${ SelinuxConfig } " ] && sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" $SelinuxConfig && setenforce 0 >/dev/null 2>& 1
2023-05-01 20:09:10 +08:00
fi
2021-10-08 00:03:44 +08:00
fi
}
## 安装环境包
2024-07-25 10:21:28 +08:00
function install_dependency_packages( ) {
2025-04-05 17:21:37 +08:00
local commands package_manager
2023-05-01 20:09:10 +08:00
## 删除原有源
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2025-05-13 06:21:27 +08:00
sed -i '/docker-ce/d' $File_AptSourceList
2025-08-08 01:44:24 +08:00
rm -rf $File_DockerSourceList
2023-05-01 20:09:10 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2023-05-10 19:39:29 +08:00
rm -rf $Dir_YumRepos /*docker*.repo
2021-10-08 00:03:44 +08:00
; ;
esac
2025-04-05 17:21:37 +08:00
## 更新软件源
commands = ( )
2023-05-01 20:09:10 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2024-11-02 03:29:54 +08:00
package_manager = "apt-get"
2025-04-05 17:21:37 +08:00
commands += ( " ${ package_manager } update " )
2021-10-08 00:03:44 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2024-11-02 03:29:54 +08:00
package_manager = " $( get_package_manager) "
2025-04-05 17:21:37 +08:00
commands += ( " ${ package_manager } makecache " )
2021-10-08 00:03:44 +08:00
; ;
esac
2025-04-05 17:21:37 +08:00
if [ [ " ${ PURE_MODE } " = = "true" ] ] ; then
local exec_cmd = ""
for cmd in " ${ commands [@] } " ; do
if [ [ -z " ${ exec_cmd } " ] ] ; then
exec_cmd = " ${ cmd } "
else
2025-07-26 20:30:38 +08:00
exec_cmd = " ${ exec_cmd } ; ${ cmd } "
2025-04-05 17:21:37 +08:00
fi
done
echo ''
animate_exec " ${ exec_cmd } " " ${ SYNC_MIRROR_TEXT } "
else
2025-09-29 01:18:46 +08:00
echo ''
2025-04-05 17:21:37 +08:00
for cmd in " ${ commands [@] } " ; do
eval " ${ cmd } "
done
fi
if [ $? -ne 0 ] ; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.sync" " ${ SYNC_MIRROR_TEXT } " " ${ BLUE } ${ package_manager } ${ PLAIN } " ) "
2021-10-08 00:03:44 +08:00
fi
2025-04-05 17:21:37 +08:00
commands = ( )
2023-05-01 20:09:10 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2025-04-05 17:21:37 +08:00
commands += ( " ${ package_manager } install -y ca-certificates curl " )
2021-10-08 00:03:44 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-04-05 17:21:37 +08:00
# 注:红帽 8 版本才发布了 dnf 包管理工具
2025-04-01 23:33:05 +08:00
case " ${ SYSTEM_VERSION_ID_MAJOR } " in
2023-05-10 19:39:29 +08:00
7)
2025-04-05 17:21:37 +08:00
commands += ( " ${ package_manager } install -y yum-utils device-mapper-persistent-data lvm2 " )
2023-05-10 19:39:29 +08:00
; ;
*)
2025-08-08 01:44:24 +08:00
if [ [ " ${ package_manager } " = = "dnf" ] ] ; then
commands += ( " ${ package_manager } install -y dnf-plugins-core " )
else
commands += ( " ${ package_manager } install -y yum-utils device-mapper-persistent-data lvm2 " )
fi
2023-05-10 19:39:29 +08:00
; ;
esac
2023-05-01 20:09:10 +08:00
; ;
2021-10-08 00:03:44 +08:00
esac
2025-04-05 17:21:37 +08:00
if [ [ " ${ PURE_MODE } " = = "true" ] ] ; then
local exec_cmd = ""
for cmd in " ${ commands [@] } " ; do
if [ [ -z " ${ exec_cmd } " ] ] ; then
exec_cmd = " ${ cmd } "
else
2025-07-26 20:30:38 +08:00
exec_cmd = " ${ exec_cmd } ; ${ cmd } "
2025-04-05 17:21:37 +08:00
fi
done
echo ''
2025-10-12 07:22:53 +08:00
animate_exec " ${ exec_cmd } " " $( msg "work.installDependents" ) "
2025-04-05 17:21:37 +08:00
else
for cmd in " ${ commands [@] } " ; do
eval " ${ cmd } "
done
fi
2021-10-08 00:03:44 +08:00
}
## 配置 Docker CE 源
2024-07-25 10:21:28 +08:00
function configure_docker_ce_mirror( ) {
2025-04-05 17:21:37 +08:00
local commands = ( )
2023-05-01 20:09:10 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2024-07-26 19:05:33 +08:00
## 处理 GPG 密钥
local file_keyring = "/etc/apt/keyrings/docker.asc"
2024-01-18 12:15:13 +08:00
apt-key del 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 >/dev/null 2>& 1 # 删除旧的密钥
2025-03-16 19:30:40 +08:00
[ -f " ${ file_keyring } " ] && rm -rf $file_keyring
2023-06-19 19:37:01 +08:00
install -m 0755 -d /etc/apt/keyrings
2025-07-18 23:26:41 +08:00
curl -fsSL " ${ WEB_PROTOCOL } :// ${ SOURCE } /linux/ ${ SOURCE_BRANCH } /gpg " -o $file_keyring >/dev/null
2024-10-07 08:17:16 +08:00
if [ $? -ne 0 ] ; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.downloadGPG" ) "
2024-10-07 08:17:16 +08:00
fi
2024-07-26 19:05:33 +08:00
chmod a+r $file_keyring
2023-06-19 19:37:01 +08:00
## 添加源
2025-09-12 11:59:41 +08:00
[ -d " ${ Dir_AptAdditionalSources } " ] || mkdir -p $Dir_AptAdditionalSources
2025-08-21 06:31:21 +08:00
local source_content = " deb [arch= $( dpkg --print-architecture) signed-by= ${ file_keyring } ] ${ WEB_PROTOCOL } :// ${ SOURCE } /linux/ ${ SOURCE_BRANCH } ${ SYSTEM_VERSION_CODENAME } stable "
echo " ${ source_content } " | tee $File_DockerSourceList >/dev/null 2>& 1
2025-04-05 17:21:37 +08:00
commands += ( "apt-get update" )
2021-10-08 00:03:44 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
local repo_file_url = " ${ WEB_PROTOCOL } :// ${ SOURCE } /linux/ ${ SOURCE_BRANCH } /docker-ce.repo "
2025-08-09 15:54:47 +08:00
local package_manager = " $( get_package_manager) "
2025-04-05 17:21:37 +08:00
case " ${ SYSTEM_VERSION_ID_MAJOR } " in
7)
2025-08-08 01:44:24 +08:00
yum-config-manager -y --add-repo " ${ repo_file_url } "
2025-04-05 17:21:37 +08:00
; ;
*)
2025-06-04 14:30:07 +08:00
if [ [ " ${ SYSTEM_JUDGMENT } " = = " ${ SYSTEM_FEDORA } " ] ] ; then
2025-08-08 01:44:24 +08:00
dnf-3 config-manager -y --add-repo " ${ repo_file_url } "
2025-06-04 14:30:07 +08:00
else
2025-08-08 01:44:24 +08:00
if [ [ " ${ package_manager } " = = "dnf" ] ] ; then
dnf config-manager -y --add-repo " ${ repo_file_url } "
else
yum-config-manager -y --add-repo " ${ repo_file_url } "
fi
2025-06-04 14:30:07 +08:00
fi
2025-04-05 17:21:37 +08:00
; ;
esac
2025-08-08 01:44:24 +08:00
sed -e " s|https://download.docker.com| ${ WEB_PROTOCOL } :// ${ SOURCE } |g " \
-e " s|http[s]\?://.*/linux/ ${ SOURCE_BRANCH } /| ${ WEB_PROTOCOL } :// ${ SOURCE } /linux/ ${ SOURCE_BRANCH } /|g " \
-i \
$File_DockerRepo
2025-09-26 20:34:11 +08:00
## 处理版本号
if [ [ " ${ SOURCE_BRANCH_VERSION } " ] ] ; then
# 指定版本
sed -e " s|\$releasever| ${ SOURCE_BRANCH_VERSION } |g " \
-i \
$File_DockerRepo
commands += ( " ${ package_manager } makecache " )
elif [ [ " ${ SYSTEM_JUDGMENT } " != " ${ SYSTEM_FEDORA } " ] ] ; then
# 兼容处理
2024-07-26 19:05:33 +08:00
local target_version
2025-04-01 23:33:05 +08:00
case " ${ SYSTEM_VERSION_ID_MAJOR } " in
2025-03-16 20:16:18 +08:00
7 | 8 | 9 | 10)
2025-04-01 23:33:05 +08:00
target_version = " ${ SYSTEM_VERSION_ID_MAJOR } "
2023-05-10 19:39:29 +08:00
; ;
*)
2025-07-18 23:26:41 +08:00
target_version = "8" # 注: 部分系统使用9版本分支会有兼容性问题
2025-08-03 09:17:23 +08:00
## 适配国产操作系统
2025-08-08 01:44:24 +08:00
# OpenCloudOS、Anolis OS 的 23 版本
if [ [ " ${ SYSTEM_JUDGMENT } " = = " ${ SYSTEM_OPENCLOUDOS } " || " ${ SYSTEM_JUDGMENT } " = = " ${ SYSTEM_ANOLISOS } " ] ] ; then
if [ [ " ${ SYSTEM_VERSION_ID_MAJOR } " = = 23 ] ] ; then
target_version = "9"
fi
fi
if [ [ " ${ SYSTEM_JUDGMENT } " = = " ${ SYSTEM_OPENEULER } " ] ] ; then
2025-08-03 09:17:23 +08:00
if [ -s " ${ File_HuaweiCloudEulerOSRelease } " ] ; then
# Huawei Cloud EulerOS
case " ${ SYSTEM_VERSION_ID_MAJOR } " in
1)
2025-08-03 09:20:14 +08:00
target_version = "8" # openEuler 20
2025-08-03 09:17:23 +08:00
; ;
2)
2025-08-03 09:20:14 +08:00
target_version = "9" # openEuler 22
; ;
2025-08-03 09:17:23 +08:00
esac
else
# openEuler
if [ [ " ${ SYSTEM_VERSION_ID_MAJOR } " -ge 22 ] ] ; then
target_version = "9"
fi
fi
2025-07-18 23:26:41 +08:00
fi
2025-08-08 01:44:24 +08:00
# TencentOS Server
if [ -s " ${ File_TencentOSServerRelease } " ] ; then
case " ${ SYSTEM_VERSION_ID_MAJOR } " in
4)
target_version = "9"
; ;
3)
target_version = "8"
; ;
2)
target_version = "7"
; ;
esac
fi
# Alibaba Cloud Linux
if [ -s " ${ File_AnolisOSRelease } " ] && [ -s " ${ File_AlibabaCloudLinuxRelease } " ] ; then
case " ${ SYSTEM_VERSION_ID_MAJOR } " in
3)
target_version = "8"
; ;
2)
target_version = "7"
; ;
esac
fi
2023-05-10 19:39:29 +08:00
; ;
esac
2025-09-26 20:34:11 +08:00
sed -e " s|\$releasever| ${ target_version } |g " \
-i \
$File_DockerRepo
2025-04-05 17:21:37 +08:00
commands += ( " ${ package_manager } makecache " )
2023-05-10 19:39:29 +08:00
fi
2021-10-08 00:03:44 +08:00
; ;
esac
2025-04-05 17:21:37 +08:00
if [ [ " ${ PURE_MODE } " = = "true" ] ] ; then
local exec_cmd = ""
for cmd in " ${ commands [@] } " ; do
if [ [ -z " ${ exec_cmd } " ] ] ; then
exec_cmd = " ${ cmd } "
else
2025-07-26 20:30:38 +08:00
exec_cmd = " ${ exec_cmd } ; ${ cmd } "
2025-04-05 17:21:37 +08:00
fi
done
2025-09-29 01:18:46 +08:00
echo ''
2025-04-05 17:21:37 +08:00
animate_exec " ${ exec_cmd } " " ${ SYNC_MIRROR_TEXT } "
else
for cmd in " ${ commands [@] } " ; do
eval " ${ cmd } "
done
fi
2021-10-08 00:03:44 +08:00
}
## 安装 Docker Engine
2024-07-25 10:21:28 +08:00
function install_docker_engine( ) {
2022-02-22 06:33:11 +08:00
## 导出可安装的版本列表
2024-07-25 10:21:28 +08:00
function export_version_list( ) {
2023-05-01 20:09:10 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2025-05-19 04:03:20 +08:00
apt-cache madison docker-ce | awk '{print $3}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$File_DockerCEVersionTmp
apt-cache madison docker-ce-cli | awk '{print $3}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$File_DockerCECliVersionTmp
grep -wf $File_DockerCEVersionTmp $File_DockerCECliVersionTmp >$File_DockerVersionTmp
2022-02-22 06:33:11 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-01-04 19:20:15 +08:00
local package_manager = " $( get_package_manager) "
2025-05-19 04:03:20 +08:00
$package_manager list docker-ce --showduplicates | sort -r | awk '{print $2}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$File_DockerCEVersionTmp
$package_manager list docker-ce-cli --showduplicates | sort -r | awk '{print $2}' | grep -Eo "[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}" >$File_DockerCECliVersionTmp
grep -wf $File_DockerCEVersionTmp $File_DockerCECliVersionTmp >$File_DockerVersionTmp
2022-02-22 06:33:11 +08:00
; ;
esac
2025-05-19 04:03:20 +08:00
rm -rf $File_DockerCEVersionTmp $File_DockerCECliVersionTmp
2022-02-22 06:33:11 +08:00
}
2025-05-12 04:55:37 +08:00
## 卸载 Docker Engine 原有版本软件包
function uninstall_original_version( ) {
2025-07-02 12:51:05 +08:00
if command_exists docker; then
2025-05-12 04:55:37 +08:00
# 先停止并禁用 Docker 服务
systemctl disable --now docker >/dev/null 2>& 1
sleep 2s
fi
# 确定需要卸载的软件包
local package_list
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
package_list = 'docker* podman podman-docker containerd runc'
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-05-12 04:55:37 +08:00
package_list = 'docker* podman podman-docker runc'
; ;
esac
# 卸载软件包并清理残留
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
apt-get remove -y $package_list >/dev/null 2>& 1
apt-get autoremove -y >/dev/null 2>& 1
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-05-12 04:55:37 +08:00
local package_manager = " $( get_package_manager) "
$package_manager remove -y $package_list >/dev/null 2>& 1
$package_manager autoremove -y >/dev/null 2>& 1
; ;
esac
}
2022-02-22 06:33:11 +08:00
## 安装
2024-07-25 10:21:28 +08:00
function install_main( ) {
2025-01-04 19:20:15 +08:00
local target_docker_version
2025-07-04 05:07:37 +08:00
local pkgs = ""
2025-04-05 17:21:37 +08:00
local commands = ( )
2023-05-10 19:39:29 +08:00
if [ [ " ${ INSTALL_LATESTED_DOCKER } " = = "true" ] ] ; then
2025-07-04 05:07:37 +08:00
pkgs = "docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"
2022-02-22 06:33:11 +08:00
else
2024-07-25 10:21:28 +08:00
export_version_list
2025-05-19 04:03:20 +08:00
if [ ! -s " ${ File_DockerVersionTmp } " ] ; then
rm -rf $File_DockerVersionTmp
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.queryVersionFailed" ) "
2025-01-04 19:20:15 +08:00
fi
if [ [ " ${ DESIGNATED_DOCKER_VERSION } " ] ] ; then
2025-05-19 04:03:20 +08:00
cat $File_DockerVersionTmp | grep -Eq " ^ ${ DESIGNATED_DOCKER_VERSION } $"
2025-01-04 19:20:15 +08:00
if [ $? -ne 0 ] ; then
2025-05-19 04:03:20 +08:00
rm -rf $File_DockerVersionTmp
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.designatedVersion" ) "
2025-01-04 19:20:15 +08:00
fi
target_docker_version = " ${ DESIGNATED_DOCKER_VERSION } "
else
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
local version_list = (
2025-05-19 04:03:20 +08:00
$( cat $File_DockerVersionTmp | sort -t '.' -k1,1nr -k2,2nr -k3,3nr | tr '\n' ' ' | sed 's/ $//' )
2025-01-04 19:20:15 +08:00
)
local mirror_list_name = "version_list"
2025-10-12 07:22:53 +08:00
interactive_select_list " ${ mirror_list_name } " " \n ${ BOLD } $( msg "interaction.install.selectVersion" ) ${ PLAIN } \n "
2025-01-04 19:20:15 +08:00
target_docker_version = " ${ _SELECT_RESULT } "
2025-10-12 07:22:53 +08:00
echo -e " \n ${ GREEN } ➜ ${ PLAIN } ${ BOLD } $( msg "interaction.install.selectedVersion" ) ${ target_docker_version } ${ PLAIN } \n "
2022-02-22 06:33:11 +08:00
else
2025-10-12 07:22:53 +08:00
echo -e " \n ${ GREEN } --------- $( msg "interaction.install.selectedTitle" "28.3.0" ) ---------- ${ PLAIN } \n "
2025-05-19 04:03:20 +08:00
cat $File_DockerVersionTmp
2025-01-04 19:20:15 +08:00
while true; do
2025-10-12 07:22:53 +08:00
local CHOICE = " $( echo -e " \n ${ BOLD } └─ $( msg "interaction.install.inputVersion" ) ${ PLAIN } \n " ) "
2025-10-09 02:58:24 +08:00
read -rp " ${ CHOICE } " target_docker_version
2025-01-04 19:20:15 +08:00
echo ''
2025-05-19 04:03:20 +08:00
cat $File_DockerVersionTmp | grep -Eqw " ${ target_docker_version } "
2025-01-04 19:20:15 +08:00
if [ $? -eq 0 ] ; then
echo " ${ target_docker_version } " | grep -Eqw '[0-9][0-9].[0-9]{1,2}.[0-9]{1,2}'
if [ $? -eq 0 ] ; then
break
else
2025-10-12 07:22:53 +08:00
echo -e " $ERROR $( msg "error.invalidVersion" ) "
2025-01-04 19:20:15 +08:00
fi
else
2025-10-12 07:22:53 +08:00
echo -e " $ERROR $( msg "error.reEnter" ) "
2025-01-04 19:20:15 +08:00
fi
done
2022-02-22 06:33:11 +08:00
fi
2025-01-04 19:20:15 +08:00
fi
2025-05-19 04:03:20 +08:00
rm -rf $File_DockerVersionTmp
2025-07-04 05:07:37 +08:00
local major_version = " $( echo ${ target_docker_version } | cut -d'.' -f1) "
local minor_version = " $( echo ${ target_docker_version } | cut -d'.' -f2) "
2023-05-01 20:09:10 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2025-07-04 05:07:37 +08:00
if [ [ $major_version -gt 18 ] ] || [ [ $major_version -eq 18 && $minor_version -ge 9 ] ] ; then
local tmp_version = " $( apt-cache madison docker-ce-cli | grep " ${ target_docker_version } " | head -1 | awk '{print $3}' | awk -F " ${ target_docker_version } " '{print$1}' ) "
pkgs = " docker-ce= ${ tmp_version } ${ target_docker_version } * docker-ce-cli= ${ tmp_version } ${ target_docker_version } * "
else
pkgs = " docker-ce= ${ target_docker_version } * docker-ce-cli= ${ target_docker_version } * "
fi
2022-02-22 06:33:11 +08:00
; ;
2025-07-04 05:07:37 +08:00
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-07-04 05:07:37 +08:00
pkgs = " docker-ce- ${ target_docker_version } "
if [ [ $major_version -gt 18 ] ] || [ [ $major_version -eq 18 && $minor_version -ge 9 ] ] ; then
pkgs = " ${ pkgs } docker-ce-cli- ${ target_docker_version } "
fi
2022-02-22 06:33:11 +08:00
; ;
esac
2025-07-04 05:07:37 +08:00
pkgs = " ${ pkgs } containerd.io "
if [ [ $major_version -gt 20 ] ] || [ [ $major_version -eq 20 && $minor_version -ge 10 ] ] ; then
pkgs = " ${ pkgs } docker-compose-plugin "
fi
if [ [ $major_version -ge 23 ] ] ; then
pkgs = " ${ pkgs } docker-buildx-plugin "
fi
2022-02-22 06:33:11 +08:00
fi
2025-07-04 05:07:37 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
commands += ( " apt-get install -y ${ pkgs } " )
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-07-04 05:07:37 +08:00
commands += ( " $( get_package_manager) install -y ${ pkgs } " )
; ;
esac
2025-09-26 20:34:11 +08:00
echo ''
2025-04-05 17:21:37 +08:00
if [ [ " ${ PURE_MODE } " = = "true" ] ] ; then
local exec_cmd = ""
for cmd in " ${ commands [@] } " ; do
if [ [ -z " ${ exec_cmd } " ] ] ; then
exec_cmd = " ${ cmd } "
else
2025-07-26 20:30:38 +08:00
exec_cmd = " ${ exec_cmd } ; ${ cmd } "
2025-04-05 17:21:37 +08:00
fi
done
2025-10-12 07:22:53 +08:00
animate_exec " ${ exec_cmd } " " $( msg "work.installDockerEngine" ) "
2025-04-05 17:21:37 +08:00
else
for cmd in " ${ commands [@] } " ; do
eval " ${ cmd } "
done
fi
2025-10-12 07:22:53 +08:00
[ $? -ne 0 ] && output_error " $( msg "error.installDockerEngineFailed" ) "
2022-02-22 06:33:11 +08:00
}
2025-01-04 19:20:15 +08:00
## 判断是否手动选择安装版本
if [ [ -z " ${ INSTALL_LATESTED_DOCKER } " ] ] ; then
2025-10-12 07:22:53 +08:00
local ask_text = " $( msg "interaction.install.latestVersion" ) ? "
2024-12-06 00:13:13 +08:00
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
2025-01-04 19:20:15 +08:00
echo ''
2025-07-18 08:26:53 +08:00
interactive_select_boolean " ${ BOLD } ${ ask_text } ${ PLAIN } "
2024-12-06 00:13:13 +08:00
if [ [ " ${ _SELECT_RESULT } " = = "true" ] ] ; then
2025-01-04 19:20:15 +08:00
INSTALL_LATESTED_DOCKER = "true"
2021-10-08 00:03:44 +08:00
else
2025-01-04 19:20:15 +08:00
INSTALL_LATESTED_DOCKER = "false"
2021-10-08 00:03:44 +08:00
fi
2025-01-04 19:20:15 +08:00
else
2025-07-18 08:26:53 +08:00
local CHOICE_A = " $( echo -e " \n ${ BOLD } └─ ${ ask_text } [Y/n] ${ PLAIN } " ) "
2025-10-09 02:58:24 +08:00
read -rp " ${ CHOICE_A } " INPUT
2024-12-06 00:13:13 +08:00
[ [ -z " ${ INPUT } " ] ] && INPUT = Y
case $INPUT in
[ Yy] | [ Yy] [ Ee] [ Ss] )
2025-01-04 19:20:15 +08:00
INSTALL_LATESTED_DOCKER = "true"
; ;
[ Nn] | [ Nn] [ Oo] )
INSTALL_LATESTED_DOCKER = "false"
2024-12-06 00:13:13 +08:00
; ;
*)
2025-01-04 19:20:15 +08:00
INSTALL_LATESTED_DOCKER = "true"
2025-10-12 07:22:53 +08:00
input_error " $( msg "error.defaultBehavior.installLatest" ) "
2024-12-06 00:13:13 +08:00
; ;
esac
2021-10-08 00:03:44 +08:00
fi
2025-01-04 19:20:15 +08:00
fi
2024-12-06 00:13:13 +08:00
2025-01-04 19:20:15 +08:00
## 判定是否已安装
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
dpkg -l | grep docker-ce-cli -q
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-01-04 19:20:15 +08:00
rpm -qa | grep docker-ce-cli -q
; ;
esac
if [ $? -eq 0 ] ; then
export_version_list
local current_docker_version = " $( docker -v | grep -Eo "[0-9][0-9]\.[0-9]{1,2}\.[0-9]{1,2}" ) "
2025-05-19 04:03:20 +08:00
local latest_docker_version = " $( cat $File_DockerVersionTmp | head -n 1) "
rm -rf $File_DockerVersionTmp
2025-01-04 19:20:15 +08:00
if [ [ " ${ current_docker_version } " = = " ${ latest_docker_version } " ] ] && [ [ " ${ INSTALL_LATESTED_DOCKER } " = = "true" ] ] ; then
2025-10-12 07:22:53 +08:00
echo -e " \n $TIP $( msg "tip.skipInstallDockerEngine" ) "
2025-05-12 04:55:37 +08:00
else
uninstall_original_version
install_main
fi
else
uninstall_original_version
install_main
fi
}
## 修改 Docker Registry 镜像仓库源
function change_docker_registry_mirror( ) {
## 使用官方 Docker Hub
if [ [ " ${ REGISTRY_SOURCEL } " = = "registry.hub.docker.com" ] ] ; then
2025-05-19 04:03:20 +08:00
if [ -s " ${ File_DockerConfig } " ] ; then
2025-05-12 04:55:37 +08:00
## 安装 jq
local package_manager = " $( get_package_manager) "
$package_manager install -y jq
2025-07-02 12:51:05 +08:00
if command_exists jq; then
2025-05-19 04:03:20 +08:00
jq 'del(.["registry-mirrors"])' $File_DockerConfig >$File_DockerConfig .tmp && mv $File_DockerConfig .tmp $File_DockerConfig
2025-05-12 04:55:37 +08:00
# 重启服务
systemctl daemon-reload
2025-08-08 01:44:24 +08:00
if [ [ " $( systemctl is-active docker 2>/dev/null) " = = "active" ] ] ; then
2025-05-12 04:55:37 +08:00
systemctl restart docker
fi
else
2025-10-12 07:22:53 +08:00
echo -e " \n ${ WARN } $( msg "warn.needManuallyDeleteConfig" " ${ File_DockerConfig } " " ${ BLUE } registry-mirrors ${ PLAIN } " " ${ BLUE } systemctl daemon-reload && systemctl restart docker ${ PLAIN } " ) \n "
2025-05-12 04:55:37 +08:00
fi
fi
return
fi
## 备份原有配置文件
2025-05-19 04:03:20 +08:00
if [ -d " ${ Dir_Docker } " ] && [ -e " ${ File_DockerConfig } " ] ; then
if [ -e " ${ File_DockerConfigBackup } " ] ; then
2025-05-12 04:55:37 +08:00
if [ [ " ${ IGNORE_BACKUP_TIPS } " = = "false" ] ] ; then
2025-10-12 07:22:53 +08:00
local ask_text = " $( msg "interaction.backup.skipOverwrite" ) ? "
2025-05-12 04:55:37 +08:00
if [ [ " ${ CAN_USE_ADVANCED_INTERACTIVE_SELECTION } " = = "true" ] ] ; then
echo ''
2025-07-18 08:26:53 +08:00
interactive_select_boolean " ${ BOLD } ${ ask_text } ${ PLAIN } "
2025-05-12 04:55:37 +08:00
if [ [ " ${ _SELECT_RESULT } " = = "false" ] ] ; then
echo ''
2025-05-19 04:03:20 +08:00
cp -rvf $File_DockerConfig $File_DockerConfigBackup 2>& 1
2025-05-12 04:55:37 +08:00
fi
else
2025-07-18 08:26:53 +08:00
local CHOICE_BACKUP = " $( echo -e " \n ${ BOLD } └─ ${ ask_text } [Y/n] ${ PLAIN } " ) "
2025-10-09 02:58:24 +08:00
read -rp " ${ CHOICE_BACKUP } " INPUT
2025-05-12 04:55:37 +08:00
[ [ -z " ${ INPUT } " ] ] && INPUT = Y
case $INPUT in
[ Yy] | [ Yy] [ Ee] [ Ss] ) ; ;
[ Nn] | [ Nn] [ Oo] )
echo ''
2025-05-19 04:03:20 +08:00
cp -rvf $File_DockerConfig $File_DockerConfigBackup 2>& 1
2025-05-12 04:55:37 +08:00
; ;
*)
2025-10-12 07:22:53 +08:00
input_error " $( msg "error.defaultBehavior.noOverwrite" ) "
2025-05-12 04:55:37 +08:00
; ;
esac
fi
fi
else
echo ''
2025-05-19 04:03:20 +08:00
cp -rvf $File_DockerConfig $File_DockerConfigBackup 2>& 1
2025-10-12 07:22:53 +08:00
echo -e " \n $COMPLETE $( msg "info.backuped.dockerConfig" ) "
2025-05-12 04:55:37 +08:00
fi
sleep 2s
else
2025-05-19 04:03:20 +08:00
mkdir -p $Dir_Docker >/dev/null 2>& 1
touch $File_DockerConfig
2025-05-12 04:55:37 +08:00
fi
2025-05-19 04:03:20 +08:00
echo -e '{\n "registry-mirrors": ["https://' " ${ SOURCE_REGISTRY } " '"]\n}' >$File_DockerConfig
2025-05-12 04:55:37 +08:00
## 重启服务
systemctl daemon-reload
2025-08-08 01:44:24 +08:00
if [ [ " $( systemctl is-active docker 2>/dev/null) " = = "active" ] ] ; then
2025-05-12 04:55:37 +08:00
systemctl restart docker
fi
}
## 仅修改 Docker Registry 镜像仓库源模式
function only_change_docker_registry_mirror( ) {
## 判定是否已安装
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
dpkg -l | grep docker-ce-cli -q
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-05-12 04:55:37 +08:00
rpm -qa | grep docker-ce-cli -q
; ;
esac
if [ $? -ne 0 ] ; then
## 仅镜像仓库换源模式
if [ [ " ${ ONLY_REGISTRY } " = = "true" ] ] ; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "result.registry.dockerEngineNotExsit" " ${ BLUE } --only-registry ${ PLAIN } " ) "
2025-05-12 04:55:37 +08:00
fi
fi
2025-05-19 04:03:20 +08:00
[ -d " ${ Dir_Docker } " ] || mkdir -p " ${ Dir_Docker } "
if [ -s " ${ File_DockerConfig } " ] ; then
2025-05-12 04:55:37 +08:00
## 安装 jq
2025-07-02 12:51:05 +08:00
if ! command_exists jq; then
2025-05-12 04:55:37 +08:00
## 更新软件源
local package_manager
local commands = ( )
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
package_manager = "apt-get"
commands += ( " ${ package_manager } update " )
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-05-12 04:55:37 +08:00
package_manager = " $( get_package_manager) "
commands += ( " ${ package_manager } makecache " )
; ;
esac
if [ [ " ${ PURE_MODE } " = = "true" ] ] ; then
local exec_cmd = ""
for cmd in " ${ commands [@] } " ; do
if [ [ -z " ${ exec_cmd } " ] ] ; then
exec_cmd = " ${ cmd } "
else
2025-07-26 20:30:38 +08:00
exec_cmd = " ${ exec_cmd } ; ${ cmd } "
2025-05-12 04:55:37 +08:00
fi
done
echo ''
animate_exec " ${ exec_cmd } " " ${ SYNC_MIRROR_TEXT } "
else
2025-09-29 01:18:46 +08:00
echo ''
2025-05-12 04:55:37 +08:00
for cmd in " ${ commands [@] } " ; do
eval " ${ cmd } "
done
fi
if [ $? -ne 0 ] ; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.sync" " ${ SYNC_MIRROR_TEXT } " " ${ BLUE } ${ package_manager } ${ PLAIN } " ) "
2025-05-12 04:55:37 +08:00
fi
$package_manager install -y jq
2025-07-02 12:51:05 +08:00
if ! command_exists jq; then
2025-10-12 07:22:53 +08:00
output_error " $( msg "error.installPackageFailed" " ${ BLUE } jq ${ PLAIN } " ) "
2025-05-12 04:55:37 +08:00
fi
2025-01-04 19:20:15 +08:00
fi
2025-05-19 04:03:20 +08:00
[ -s " ${ File_DockerConfig } " ] || echo "{}" >$File_DockerConfig
jq '.["registry-mirrors"] = ["https://' " ${ SOURCE_REGISTRY } " '"]' $File_DockerConfig >$File_DockerConfig .tmp && mv $File_DockerConfig .tmp $File_DockerConfig
2025-05-12 04:55:37 +08:00
else
2025-05-19 04:03:20 +08:00
echo -e '{\n "registry-mirrors": ["https://' " ${ SOURCE_REGISTRY } " '"]\n}' >$File_DockerConfig
2025-05-12 04:55:37 +08:00
fi
echo -e " \n ${ BLUE } \$ ${ PLAIN } docker info --format '{{json .RegistryConfig.Mirrors}}' "
2025-05-19 04:03:20 +08:00
echo -e " \n ${ GREEN } ➜ ${ PLAIN } $( docker info --format '{{json .RegistryConfig.Mirrors}}' ) "
2025-05-12 04:55:37 +08:00
## 重启服务
systemctl daemon-reload
2025-08-08 01:44:24 +08:00
if [ [ " $( systemctl is-active docker 2>/dev/null) " = = "active" ] ] ; then
2025-05-12 04:55:37 +08:00
systemctl restart docker
fi
if [ [ " ${ PURE_MODE } " != "true" ] ] ; then
2025-10-12 07:22:53 +08:00
echo -e " \n $COMPLETE $( msg "result.registry.success" ) "
2021-10-08 00:03:44 +08:00
fi
}
## 查看版本并验证安装结果
2025-05-12 04:55:37 +08:00
function check_installed_result( ) {
2025-07-02 12:51:05 +08:00
if command_exists docker; then
2025-01-04 19:20:15 +08:00
systemctl enable --now docker >/dev/null 2>& 1
2025-09-29 01:18:46 +08:00
echo -en " \n $COMPLETE "
2023-05-10 19:39:29 +08:00
docker -v
2024-12-13 21:50:49 +08:00
if [ $? -eq 0 ] ; then
2025-09-29 01:18:46 +08:00
echo -e " $( docker compose version 2>& 1) "
2025-04-01 23:33:05 +08:00
# echo -e "\n$COMPLETE 安装完成"
2023-05-10 19:39:29 +08:00
else
2025-10-12 07:22:53 +08:00
echo -e " \n $FAIL $( msg "result.install.failed" ) "
2025-07-18 08:26:53 +08:00
local source_file package_manager
2023-05-10 19:39:29 +08:00
case " ${ SYSTEM_FACTIONS } " in
" ${ SYSTEM_DEBIAN } " )
2025-08-08 01:44:24 +08:00
source_file = " ${ File_DockerSourceList } "
2025-07-18 08:26:53 +08:00
package_manager = "apt-get"
2023-05-10 19:39:29 +08:00
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_REDHAT } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
source_file = " ${ File_DockerRepo } "
2025-07-18 08:26:53 +08:00
package_manager = " $( get_package_manager) "
2023-05-10 19:39:29 +08:00
; ;
esac
2025-10-12 07:22:53 +08:00
echo -e " \n $( msg "result.install.checkSourceFile" " cat ${ source_file } " ) "
echo -e " $( msg "result.install.manuallyExecCmd" " ${ package_manager } install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin " ) \n "
2023-05-10 19:39:29 +08:00
exit 1
fi
2025-08-08 01:44:24 +08:00
if [ [ " $( systemctl is-active docker 2>/dev/null) " != "active" ] ] ; then
2023-05-10 19:39:29 +08:00
sleep 2
systemctl disable --now docker >/dev/null 2>& 1
sleep 2
systemctl enable --now docker >/dev/null 2>& 1
sleep 2
2025-08-08 01:44:24 +08:00
if [ [ " $( systemctl is-active docker) " != "active" ] ] ; then
2025-10-12 07:22:53 +08:00
echo -e " \n $WARN $( msg "result.install.notRunning" ) "
2025-08-08 01:44:24 +08:00
local start_cmd
if command_exists systemctl; then
start_cmd = "systemctl start docker"
else
start_cmd = "service docker start"
fi
2025-10-12 07:22:53 +08:00
echo -e " \n $TIP $( msg "result.install.manuallyRun" " ${ BLUE } ${ start_cmd } ${ PLAIN } " ) "
2023-05-10 19:39:29 +08:00
fi
2021-10-08 00:03:44 +08:00
fi
2023-05-10 19:39:29 +08:00
else
2025-10-12 07:22:53 +08:00
echo -e " \n $FAIL $( msg "result.install.failed" ) "
2021-10-08 00:03:44 +08:00
fi
}
2025-05-12 04:55:37 +08:00
## 选择系统包管理器
function get_package_manager( ) {
local command = "yum"
case " ${ SYSTEM_JUDGMENT } " in
2025-07-18 09:26:32 +08:00
" ${ SYSTEM_RHEL } " | " ${ SYSTEM_CENTOS_STREAM } " | " ${ SYSTEM_ROCKY } " | " ${ SYSTEM_ALMALINUX } " | " ${ SYSTEM_ORACLE } " )
2025-05-12 04:55:37 +08:00
case " ${ SYSTEM_VERSION_ID_MAJOR } " in
9 | 10)
command = "dnf"
; ;
esac
; ;
2025-08-08 01:44:24 +08:00
" ${ SYSTEM_FEDORA } " | " ${ SYSTEM_OPENEULER } " | " ${ SYSTEM_OPENCLOUDOS } " | " ${ SYSTEM_ANOLISOS } " | " ${ SYSTEM_TENCENTOS } " )
2025-05-12 04:55:37 +08:00
command = "dnf"
; ;
esac
echo " ${ command } "
}
2025-10-12 07:22:53 +08:00
function interactive_select_list( ) {
2024-12-06 00:13:13 +08:00
_SELECT_RESULT = ""
2025-10-12 07:22:53 +08:00
eval " local __values=(\"\${ ${ 1 } [@]}\") "
local __labels = ( )
local message = " ${ 2 } "
2024-12-06 00:13:13 +08:00
local selected = 0
local start = 0
2025-07-18 08:26:53 +08:00
local page_size = $(( $( tput lines 2>/dev/null) - 3 ))
2025-10-12 07:22:53 +08:00
if [ [ " ${ 3 } " ] ] ; then
eval " __labels=(\"\${ ${ 3 } [@]}\") "
fi
2024-12-06 00:13:13 +08:00
function clear_menu( ) {
2025-03-20 23:11:18 +08:00
tput rc 2>/dev/null
2025-10-12 07:22:53 +08:00
for ( ( i = 0; i < ${# __values [@] } + 1; i++) ) ; do
2024-12-06 00:13:13 +08:00
echo -e "\r\033[K"
done
2025-03-20 23:11:18 +08:00
tput rc 2>/dev/null
2024-12-06 00:13:13 +08:00
}
function cleanup( ) {
clear_menu
2025-03-20 23:11:18 +08:00
tput rc 2>/dev/null
tput cnorm 2>/dev/null
tput rmcup 2>/dev/null
2025-10-12 07:22:53 +08:00
echo -e " \n\033[1;44m $( msg "interaction.common.tip" ) \033[0m \033[31m $( msg "interaction.common.operationCanceled" ) \033[0m\n "
2025-03-17 01:01:49 +08:00
exit 130
2024-12-06 00:13:13 +08:00
}
function draw_menu( ) {
2025-03-20 23:11:18 +08:00
tput clear 2>/dev/null
tput cup 0 0 2>/dev/null
2024-12-06 00:13:13 +08:00
echo -e " ${ message } "
local end = $(( start + page_size - 1 ))
2025-10-12 07:22:53 +08:00
local label
if [ $end -ge ${# __values [@] } ] ; then
end = ${# __values [@] } -1
2024-12-06 00:13:13 +08:00
fi
for ( ( i = start; i <= end; i++) ) ; do
2025-10-12 07:22:53 +08:00
if [ [ " ${ __labels [ $i ] } " ] ] ; then
label = " ${ __labels [ $i ] } "
else
label = " ${ __values [ $i ] } "
fi
if [ " $i " -eq " ${ selected } " ] ; then
echo -e " \e[34;4m➤ ${ label } \e[0m "
2024-12-06 00:13:13 +08:00
else
2025-10-12 07:22:53 +08:00
echo -e " ${ label } "
2024-12-06 00:13:13 +08:00
fi
done
}
function read_key( ) {
IFS = read -rsn1 key
if [ [ $key = = $'\x1b' ] ] ; then
IFS = read -rsn2 key
key = " $key "
fi
echo " $key "
}
2025-07-18 08:26:53 +08:00
tput smcup 2>/dev/null
tput sc 2>/dev/null
tput civis 2>/dev/null
trap "cleanup" INT TERM
draw_menu
2024-12-06 00:13:13 +08:00
while true; do
key = $( read_key)
case " $key " in
2024-12-13 21:50:49 +08:00
"[A" | "w" | "W" )
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -gt 0 ] ; then
2024-12-06 00:13:13 +08:00
selected = $(( selected - 1 ))
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -lt " $start " ] ; then
2024-12-06 00:13:13 +08:00
start = $(( start - 1 ))
fi
fi
; ;
2024-12-13 21:50:49 +08:00
"[B" | "s" | "S" )
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -lt $(( ${# __values [@] } - 1 )) ] ; then
2024-12-06 00:13:13 +08:00
selected = $(( selected + 1 ))
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -ge $(( start + page_size)) ] ; then
2024-12-06 00:13:13 +08:00
start = $(( start + 1 ))
fi
fi
; ;
"" )
tput rmcup
break
; ;
*) ; ;
esac
draw_menu
done
2025-07-18 08:26:53 +08:00
tput cnorm 2>/dev/null
tput rmcup 2>/dev/null
2025-10-12 07:22:53 +08:00
_SELECT_RESULT = " ${ __values [ ${ selected } ] } "
if [ " ${ __labels [ ${ selected } ] } " ] ; then
_SELECT_RESULT = " ${ _SELECT_RESULT } @@ ${ __labels [ ${ selected } ] } "
fi
2024-12-06 00:13:13 +08:00
}
function interactive_select_boolean( ) {
_SELECT_RESULT = ""
local selected = 0
local message = " $1 "
2025-10-12 07:22:53 +08:00
local positive_title = " ${ 2 :- " $( msg "interaction.common.yes" ) " } "
local negative_title = " ${ 3 :- " $( msg "interaction.common.no" ) " } "
2025-07-18 08:26:53 +08:00
local menu_height = 3
2025-03-17 00:02:32 +08:00
local original_line
function store_position( ) {
2025-03-20 23:11:18 +08:00
original_line = $( tput lines 2>/dev/null)
2025-03-17 00:02:32 +08:00
}
2024-12-06 00:13:13 +08:00
function clear_menu( ) {
2025-09-29 01:18:46 +08:00
for ( ( i = 0; i < $menu_height ; i++) ) ; do
2025-07-18 08:26:53 +08:00
tput cuu1 2>/dev/null
tput el 2>/dev/null
2024-12-06 00:13:13 +08:00
done
}
function cleanup( ) {
clear_menu
2025-03-20 23:11:18 +08:00
tput cnorm 2>/dev/null
2025-10-12 07:22:53 +08:00
echo -e " \n\033[1;44m $( msg "interaction.common.tip" ) \033[0m \033[31m $( msg "interaction.common.operationCanceled" ) \033[0m\n "
2025-03-17 01:01:49 +08:00
exit 130
2024-12-06 00:13:13 +08:00
}
function draw_menu( ) {
echo -e " ╭─ ${ message } "
echo -e "│"
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -eq 0 ] ; then
2025-09-29 01:18:46 +08:00
echo -e " ╰─ \033[34m●\033[0m ${ positive_title } \033[2m / ○ ${ negative_title } \033[0m "
2024-12-06 00:13:13 +08:00
else
2025-09-29 01:18:46 +08:00
echo -e " ╰─ \033[2m○ ${ positive_title } / \033[0m\033[34m●\033[0m ${ negative_title } "
2024-12-06 00:13:13 +08:00
fi
}
function read_key( ) {
IFS = read -rsn1 key
if [ [ $key = = $'\x1b' ] ] ; then
IFS = read -rsn2 key
key = " $key "
fi
echo " $key "
}
2025-07-18 08:26:53 +08:00
tput civis 2>/dev/null
store_position
2025-03-17 00:02:32 +08:00
trap "cleanup" INT TERM
2025-07-18 08:26:53 +08:00
draw_menu
2024-12-06 00:13:13 +08:00
while true; do
key = $( read_key)
case " $key " in
2024-12-13 21:50:49 +08:00
"[D" | "a" | "A" )
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -gt 0 ] ; then
2024-12-06 00:13:13 +08:00
selected = $(( selected - 1 ))
2025-03-17 00:02:32 +08:00
clear_menu
draw_menu
2024-12-06 00:13:13 +08:00
fi
; ;
2024-12-13 21:50:49 +08:00
"[C" | "d" | "D" )
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -lt 1 ] ; then
2024-12-06 00:13:13 +08:00
selected = $(( selected + 1 ))
2025-03-17 00:02:32 +08:00
clear_menu
draw_menu
2024-12-06 00:13:13 +08:00
fi
; ;
"" )
2025-07-18 08:26:53 +08:00
clear_menu
2024-12-06 00:13:13 +08:00
break
; ;
*) ; ;
esac
done
2025-03-17 00:02:32 +08:00
echo -e " ╭─ ${ message } "
echo -e "│"
2025-10-12 07:22:53 +08:00
if [ " ${ selected } " -eq 0 ] ; then
2025-09-29 01:18:46 +08:00
echo -e " ╰─ \033[32m●\033[0m \033[1m ${ positive_title } \033[0m\033[2m / ○ ${ negative_title } \033[0m "
2024-12-06 00:13:13 +08:00
_SELECT_RESULT = "true"
else
2025-09-29 01:18:46 +08:00
echo -e " ╰─ \033[2m○ ${ positive_title } / \033[0m\033[32m●\033[0m \033[1m ${ negative_title } \033[0m "
2024-12-06 00:13:13 +08:00
_SELECT_RESULT = "false"
fi
2025-07-18 08:26:53 +08:00
tput cnorm 2>/dev/null
2024-12-06 00:13:13 +08:00
}
2025-04-05 17:21:37 +08:00
function animate_exec( ) {
local cmd = " $1 "
local title = " $2 "
2025-07-18 08:26:53 +08:00
local max_lines = ${ 3 :- 5 }
local spinner_style = " ${ 4 :- dots } "
local refresh_rate = " ${ 5 :- 0 .1 } "
2025-04-05 17:21:37 +08:00
local -A spinners = ( [ dots] = "⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏" [ circle] = "◐ ◓ ◑ ◒" [ classic] = "-\\ |/" )
local -A recommended_rates = ( [ dots] = "0.08" [ circle] = "0.12" [ classic] = "0.12" )
[ [ -z " ${ spinners [ $spinner_style ] } " ] ] && spinner_style = "dots"
[ [ " ${ refresh_rate } " = = "0.1" ] ] && refresh_rate = " ${ recommended_rates [ $spinner_style ] } "
local term_width = $( tput cols 2>/dev/null || echo 80)
local display_width = $(( term_width - 2 ))
function simple_truncate( ) {
local line = " $1 "
local truncate_marker = "..."
local max_length = $(( display_width - 3 ))
if [ [ " ${ line } " = ~ ^[ [ :ascii:] ] *$ && ${# line } -le $display_width ] ] ; then
echo " ${ line } "
return
fi
2025-10-09 02:58:24 +08:00
local non_ascii_count = $( echo " ${ line } " | sed "s|[0-9a-zA-Z -~]||g; s| ||g" | wc -m)
2025-04-05 17:21:37 +08:00
local total_length = ${# line }
local display_length = $(( total_length + non_ascii_count))
local quote_count = 0
2025-10-09 02:58:24 +08:00
[ [ $( echo " ${ line } " | grep -c "“" ) -gt 0 ] ] && ( ( quote_count += " $( echo " ${ line } " | grep -c "“" ) " ) )
[ [ $( echo " ${ line } " | grep -c "”" ) -gt 0 ] ] && ( ( quote_count += " $( echo " ${ line } " | grep -c "”" ) " ) )
[ [ $( echo " ${ line } " | grep -c "‘ " ) -gt 0 ] ] && ( ( quote_count += " $( echo " ${ line } " | grep -c "‘ " ) " ) )
[ [ $( echo " ${ line } " | grep -c "’ " ) -gt 0 ] ] && ( ( quote_count += " $( echo " ${ line } " | grep -c "’ " ) " ) )
2025-04-05 17:21:37 +08:00
display_length = $(( display_length - quote_count))
if [ [ $display_length -le $display_width ] ] ; then
echo " $line "
return
fi
local result = ""
local current_width = 0
local i = 0
while [ $i -lt ${# line } ] ; do
local char = " ${ line : $i : 1 } "
local char_width = 1
2025-10-09 02:58:24 +08:00
if ! [ [ " $char " = ~ [ 0-9a-zA-Z\. \= \: \_ \( \) \' \" \- \/ \! \· ] ] ] ; then
2025-04-05 17:21:37 +08:00
if [ [ " $char " != "“" && " $char " != "”" && " $char " != "‘ " && " $char " != "’ " ] ] ; then
char_width = 2
fi
fi
if [ [ $(( current_width + char_width)) -gt $max_length ] ] ; then
echo " ${ result } ${ truncate_marker } "
return
fi
result += " ${ char } "
current_width = $(( current_width + char_width))
( ( i++) )
done
echo " ${ line } "
}
function cleanup( ) {
[ -f " ${ temp_file } " ] && rm -f " ${ temp_file } "
tput cnorm 2>/dev/null
2025-10-12 07:22:53 +08:00
echo -e " \n\033[1;44m $( msg "interaction.common.tip" ) \033[0m \033[31m $( msg "interaction.common.operationCanceled" ) \033[0m\n "
2025-04-05 17:21:37 +08:00
exit 130
}
function make_temp_file( ) {
local temp_dirs = ( "." "/tmp" )
local tmp_file = ""
for dir in " ${ temp_dirs [@] } " ; do
[ [ ! -d " ${ dir } " || ! -w " ${ dir } " ] ] && continue
tmp_file = " ${ dir } /animate_exec_ $$ _ $( date +%s) "
touch " ${ tmp_file } " 2>/dev/null || continue
if [ [ -f " ${ tmp_file } " && -w " ${ tmp_file } " ] ] ; then
echo " ${ tmp_file } "
return
fi
done
echo " ${ tmp_file } "
}
function update_display( ) {
local current_size = $( wc -c <" ${ temp_file } " 2>/dev/null || echo 0)
if [ [ $current_size -le $last_size ] ] ; then
return 1
fi
local -a lines = ( )
mapfile -t -n " ${ max_lines } " lines < <( tail -n " $max_lines " " ${ temp_file } " )
local -a processed_lines = ( )
for ( ( i = 0; i < ${# lines [@] } ; i++) ) ; do
processed_lines[ i] = $( simple_truncate " ${ lines [i] } " )
done
2025-07-18 08:26:53 +08:00
tput cud1 2>/dev/null
echo -ne "\r\033[K"
tput cud1 2>/dev/null
2025-04-05 17:21:37 +08:00
for ( ( i = 0; i < $max_lines ; i++) ) ; do
2025-07-18 08:26:53 +08:00
echo -ne "\r\033[K"
2025-04-05 17:21:37 +08:00
[ [ $i -lt ${# processed_lines [@] } ] ] && echo -ne " \033[2m ${ processed_lines [ $i ] } \033[0m "
[ [ $i -lt $(( max_lines - 1 )) ] ] && tput cud1 2>/dev/null
done
for ( ( i = 0; i < $max_lines + 1; i++) ) ; do
tput cuu1 2>/dev/null
done
last_size = $current_size
return 0
}
local spinner_frames = ( ${ spinners [ $spinner_style ] } )
local temp_file = " $( make_temp_file) "
trap "cleanup" INT TERM
2025-07-18 08:26:53 +08:00
tput civis 2>/dev/null
echo ''
echo ''
2025-04-05 17:21:37 +08:00
for ( ( i = 0; i < $max_lines ; i++) ) ; do
echo ''
done
eval " ${ cmd } " >" ${ temp_file } " 2>& 1 &
local cmd_pid = $!
local last_size = 0
local spin_idx = 0
tput cuu $(( max_lines + 2 )) 2>/dev/null
sleep 0.05
echo -ne " \r\033[K◉ ${ title } [\033[1m\033[34m ${ spinner_frames [ $spin_idx ] } \033[0m] "
spin_idx = $(( ( spin_idx + 1 ) % ${# spinner_frames [@] } ))
update_display
local update_count = 0
local adaptive_rate = $refresh_rate
while kill -0 $cmd_pid 2>/dev/null; do
echo -ne " \r\033[K◉ ${ title } [\033[1m\033[34m ${ spinner_frames [ $spin_idx ] } \033[0m] "
spin_idx = $(( ( spin_idx + 1 ) % ${# spinner_frames [@] } ))
if update_display; then
update_count = $(( update_count + 1 ))
if [ [ $update_count -gt 5 ] ] ; then
adaptive_rate = $( awk " BEGIN {print $adaptive_rate * 1.5; exit} " )
[ [ $( awk " BEGIN {print ( $adaptive_rate > 0.5); exit} " ) -eq 1 ] ] && adaptive_rate = 0.5
update_count = 0
fi
else
update_count = 0
adaptive_rate = $refresh_rate
fi
sleep $adaptive_rate
done
wait $cmd_pid
local exit_status = $?
update_display
if [ $exit_status -eq 0 ] ; then
echo -ne " \r\033[K◉ ${ title } [\033[1m\033[32m✓\033[0m]\n "
else
echo -ne " \r\033[K◉ ${ title } [\033[1m\033[31m✗\033[0m]\n "
fi
echo -ne "\r\033[K\n"
local actual_lines = $( wc -l <" ${ temp_file } " 2>/dev/null || echo 0)
[ [ $actual_lines -gt $max_lines ] ] && actual_lines = $max_lines
if [ [ $actual_lines -gt 0 ] ] ; then
local -a final_lines = ( )
mapfile -t -n " $actual_lines " final_lines < <( tail -n " $actual_lines " " ${ temp_file } " )
for ( ( i = 0; i < actual_lines; i++) ) ; do
local line = $( simple_truncate " ${ final_lines [ $i ] } " )
echo -ne " \r\033[K\033[2m ${ line } \033[0m\n "
done
fi
tput cnorm 2>/dev/null
rm -f " ${ temp_file } "
return $exit_status
}
2025-10-12 07:22:53 +08:00
##############################################################################
MESSAGE_LANG_DEFAULT = 'zh-hans'
MESSAGE_LANG_KEYS = (
"zh-hans"
"zh-hant"
"en"
)
declare -A MESSAGE_LANG_DISPLAY = (
[ 'zh-hans' ] = '简体中文'
[ 'zh-hant' ] = '繁體中文'
[ 'en' ] = 'English'
)
declare -A MESSAGE_CONTENTS
function msg( ) {
local key = " $1 "
shift
local text = " ${ MESSAGE_CONTENTS [ ${ key } ] } "
if [ [ -z " ${ text } " ] ] ; then
echo " ${ key } "
return
fi
while [ [ $# -gt 0 ] ] ; do
if [ [ " ${ text } " = = *"{}" * ] ] ; then
text = " ${ text / \{ \} / $1 } "
else
break
fi
shift
done
echo " ${ text } "
}
function init_msg_pack( ) {
function load_pack( ) {
local func_name = " ${ 1 } "
if declare -f " ${ func_name } " >/dev/null 2>& 1; then
eval " ${ func_name } "
fi
}
local current_lang = " ${ 1 :- " ${ MESSAGE_LANG_DEFAULT } " } "
current_lang = " $( echo " ${ current_lang } " | sed 's/^-*//' ) "
current_lang = " ${ current_lang ,, } "
if [ [ " ${ MESSAGE_LANG_DISPLAY [ ${ current_lang } ] } " ] ] ; then
current_lang = " ${ current_lang //-/_ } "
load_pack " msg_pack_ ${ current_lang } "
fi
}
function msg_pack_zh_hans( ) {
MESSAGE_CONTENTS = (
[ 'start.welcome' ] = '欢迎使用 Docker Engine 安装与换源脚本'
[ 'start.runtimeEnv' ] = '运行环境'
[ 'start.dateTime' ] = '系统时间'
[ 'end.moreInfo' ] = '脚本运行完毕,更多使用教程详见官网'
[ 'end.sponsorAds' ] = '【赞助商广告】'
[ 'error.cmd.options.needConfirm' ] = '请确认后重新输入'
[ 'error.cmd.options.needSpecify' ] = '请在该选项后指定{}'
[ 'error.cmd.options.invalid' ] = '命令选项 {} 无效,{}! '
[ 'error.cmd.options.validAddress' ] = '有效的地址'
[ 'error.cmd.options.sourceAddress' ] = '软件源地址'
[ 'error.cmd.options.registryAddress' ] = '镜像仓库地址'
[ 'error.cmd.options.sourceRepository' ] = '软件源仓库'
[ 'error.cmd.options.validVersion' ] = '有效的版本号'
[ 'error.cmd.options.ceRepositoryVersion' ] = 'Docker CE 软件源仓库的版本号'
[ 'error.cmd.options.version' ] = '版本号'
[ 'error.cmd.options.codename' ] = '版本代号'
[ 'error.cmd.options.boolean' ] = ' true 或 false '
[ 'error.cmd.options.protocol' ] = ' http 或 https '
[ 'error.cmd.options.needProtocol' ] = ' Web 协议(http/https)'
[ 'error.cmd.options.validLangKey' ] = '有效的语言 ID '
[ 'error.cmd.options.langKey' ] = '语言 '
[ 'error.unsupportSystem1' ] = '不支持当前操作系统({}) '
[ 'error.unsupportSystem2' ] = '不支持当前操作系统({}),请参考如下命令自行安装:'
[ 'error.unknownSystem' ] = '未知系统'
[ 'error.unsupportX86_32' ] = 'Docker Engine 不支持安装在 x86_32 架构的环境上!'
[ 'error.unknownArch' ] = '未知的系统架构:{}'
[ 'error.unsupportS390x' ] = '请查阅 RHEL 发行版声明以了解 s390x 支持'
[ 'error.input' ] = '输入错误,{}! '
[ 'error.needRoot' ] = '权限不足,请使用 Root 用户运行本脚本'
[ 'error.sync' ] = '{}出错,请先解决系统原有软件源错误以确保 {} 软件包管理工具可用!'
[ 'error.downloadGPG' ] = 'GPG 密钥下载失败,请检查网络或更换 Docker CE 软件源后重试!'
[ 'error.queryVersionFailed' ] = '查询 Docker Engine 版本列表失败!'
[ 'error.designatedVersion' ] = '指定的 Docker Engine 版本不存在或不支持安装!'
[ 'error.invalidVersion' ] = '请输入正确的版本号!'
[ 'error.reEnter' ] = '输入错误请重新输入!'
[ 'error.installDockerEngineFailed' ] = '安装 Docker Engine 失败!'
[ 'error.installPackageFailed' ] = '软件包 {} 安装失败,请自行安装后重新运行脚本!'
[ 'error.defaultBehavior.https' ] = '默认使用 HTTPS 协议'
[ 'error.defaultBehavior.noClose' ] = '默认不关闭'
[ 'error.defaultBehavior.installLatest' ] = '默认安装最新版本'
[ 'error.defaultBehavior.noOverwrite' ] = '默认不覆盖'
[ 'error.defaultBehavior.noUseIntranetSource' ] = '默认不使用内网地址'
[ 'warn.usedCentosBranch' ] = '当前采用 centos 分支(红帽衍生操作系统安装方式)进行安装,可能存在某些无法预料的兼容性问题!'
[ 'warn.usedIntranetSource' ] = '已切换至内网专用地址,仅限在特定环境下使用!'
[ 'warn.needValidNumberIndex' ] = '请输入有效的数字序号!'
[ 'warn.needInputNumberIndex' ] = '请输入数字序号!'
[ 'warn.needManuallyDeleteConfig' ] = '请自行删除 {} 中的 {} 配置并重启服务 {}'
[ 'tip.unsupportRHEL10' ] = 'Docker 官方尚未支持 RHEL 10 且红帽官方已将 Docker 从注册软件源中移除并默认使用 Podman。'
[ 'tip.skipInstallDockerEngine' ] = '检测到系统已安装 Docker Engine 且是最新版本,跳过安装'
[ 'info.backuped.dockerConfig' ] = '已备份原有 Docker 配置文件'
[ 'interaction.source.type.public' ] = '公网'
[ 'interaction.source.type.intranet' ] = '内网'
[ 'interaction.source.type.select' ] = '请选择 Docker CE 源的网络地址(访问方式): '
[ 'interaction.source.type.usePublicAddress' ] = '默认使用 Docker CE 源的公网地址,是否继续'
[ 'interaction.source.dockerCE.select' ] = '请选择你想使用的 Docker CE 源:'
[ 'interaction.source.dockerCE.selectAndInput' ] = '请选择并输入你想使用的 Docker CE 源'
[ 'interaction.source.dockerRegistry.select' ] = '请选择你想使用的 Docker Registry 源:'
[ 'interaction.source.dockerRegistry.selectAndInput' ] = '请选择并输入你想使用的 Docker Registry 源'
[ 'interaction.protocol.select' ] = '请选择 Docker CE 软件源的网络协议:'
[ 'interaction.protocol.useHttp' ] = 'Docker CE 软件源是否使用 HTTP 协议'
[ 'interaction.firewall.close' ] = '是否关闭系统防火墙和 SELinux '
[ 'interaction.install.selectVersion' ] = '请选择你想安装的版本:'
[ 'interaction.install.selectedVersion' ] = '指定安装版本:'
[ 'interaction.install.selectedTitle' ] = '请选择你要安装的版本,如:{}'
[ 'interaction.install.inputVersion' ] = '请根据上面的列表,选择并输入你想要安装的具体版本号:'
[ 'interaction.install.latestVersion' ] = 'Docker Engine 是否安装最新版本'
[ 'interaction.backup.skipOverwrite' ] = '检测到已备份的 Docker 配置文件,是否跳过覆盖备份'
[ 'interaction.common.tip' ] = '提示'
[ 'interaction.common.operationCanceled' ] = '操作已取消'
[ 'interaction.common.yes' ] = '是'
[ 'interaction.common.no' ] = '否'
[ 'work.installDependents' ] = '安装环境软件包'
[ 'work.installDockerEngine' ] = '安装 Docker Engine'
[ 'source.sync.text1' ] = '更新软件源'
[ 'source.sync.text2' ] = '生成软件源缓存'
[ 'result.install.failed' ] = '安装失败'
[ 'result.install.checkSourceFile' ] = '检查源文件:'
[ 'result.install.manuallyExecCmd' ] = '请尝试手动执行安装命令:{}'
[ 'result.install.notRunning' ] = '检测到 Docker 服务启动异常,可尝试再次执行本脚本重试'
[ 'result.install.manuallyRun' ] = '请执行 {} 命令尝试启动或自行查询错误原因'
[ 'result.registry.success' ] = '已更换镜像仓库'
[ 'result.registry.dockerEngineNotExsit' ] = '当前尚未安装 Docker Engine, 请取消设置 {} 命令选项后重新执行脚本!'
[ 'commands.help' ] = ' 命令选项( 名称/含义/值) :
--source 指定 Docker CE 软件源地址( 域名或IP) 地址
--source-registry 指定 Docker 镜像仓库地址( 域名或IP) 地址
--branch 指定 Docker CE 软件源仓库( 路径) 仓库名
--branch-version 指定 Docker CE 软件源仓库版本 版本号
--designated-version 指定 Docker Engine 安装版本 版本号
--codename 指定 Debian 系操作系统的版本代号 代号名称
--protocol 指定 Docker CE 软件源的 Web 协议 http 或 https
--use-intranet-source 是否优先使用内网 Docker CE 软件源地址 true 或 false
--install-latest 是否安装最新版本的 Docker Engine true 或 false
--close-firewall 是否关闭防火墙 true 或 false
--clean-screen 是否在运行前清除屏幕上的所有内容 true 或 false
--lang 指定脚本使用的语言 ID 语言
--only-registry 仅更换镜像仓库模式 无
--ignore-backup-tips 忽略覆盖备份提示 无
--pure-mode 纯净模式,精简打印内容 无
--help 查看帮助菜单 无
问题报告 { } '
[ 'mirrors.dockerCE.0' ] = '阿里云'
[ 'mirrors.dockerCE.1' ] = '腾讯云'
[ 'mirrors.dockerCE.2' ] = '华为云'
[ 'mirrors.dockerCE.3' ] = '网易'
[ 'mirrors.dockerCE.4' ] = '火山引擎'
[ 'mirrors.dockerCE.5' ] = '微软 Azure 中国'
[ 'mirrors.dockerCE.6' ] = '清华大学'
[ 'mirrors.dockerCE.7' ] = '北京大学'
[ 'mirrors.dockerCE.8' ] = '浙江大学'
[ 'mirrors.dockerCE.9' ] = '南京大学'
[ 'mirrors.dockerCE.10' ] = '上海交通大学'
[ 'mirrors.dockerCE.11' ] = '重庆邮电大学'
[ 'mirrors.dockerCE.12' ] = '中国科学技术大学'
[ 'mirrors.dockerCE.13' ] = '中国科学院软件研究所'
[ 'mirrors.dockerCE.14' ] = '官方源'
[ 'mirrors.registry.0' ] = '毫秒镜像(推荐)'
[ 'mirrors.registry.1' ] = 'Docker Proxy'
[ 'mirrors.registry.2' ] = 'DaoCloud 道客'
[ 'mirrors.registry.3' ] = '1Panel 镜像'
[ 'mirrors.registry.4' ] = '阿里云(杭州)'
[ 'mirrors.registry.5' ] = '阿里云(上海)'
[ 'mirrors.registry.6' ] = '阿里云(青岛)'
[ 'mirrors.registry.7' ] = '阿里云(北京)'
[ 'mirrors.registry.8' ] = '阿里云(张家口)'
[ 'mirrors.registry.9' ] = '阿里云(呼和浩特)'
[ 'mirrors.registry.10' ] = '阿里云(乌兰察布)'
[ 'mirrors.registry.11' ] = '阿里云(深圳)'
[ 'mirrors.registry.12' ] = '阿里云(河源)'
[ 'mirrors.registry.13' ] = '阿里云(广州)'
[ 'mirrors.registry.14' ] = '阿里云(成都)'
[ 'mirrors.registry.15' ] = '阿里云(香港)'
[ 'mirrors.registry.16' ] = '阿里云(日本-东京)'
[ 'mirrors.registry.17' ] = '阿里云(新加坡)'
[ 'mirrors.registry.18' ] = '阿里云(马来西亚-吉隆坡)'
[ 'mirrors.registry.19' ] = '阿里云(印度尼西亚-雅加达)'
[ 'mirrors.registry.20' ] = '阿里云(德国-法兰克福)'
[ 'mirrors.registry.21' ] = '阿里云(英国-伦敦)'
[ 'mirrors.registry.22' ] = '阿里云(美国西部-硅谷)'
[ 'mirrors.registry.23' ] = '阿里云(美国东部-弗吉尼亚)'
[ 'mirrors.registry.24' ] = '阿里云(阿联酋-迪拜)'
[ 'mirrors.registry.25' ] = '腾讯云'
[ 'mirrors.registry.26' ] = '谷歌云(北美)'
[ 'mirrors.registry.27' ] = '谷歌云(亚洲)'
[ 'mirrors.registry.28' ] = '谷歌云(欧洲)'
[ 'mirrors.registry.29' ] = '官方 Docker Hub'
)
}
function msg_pack_zh_hant( ) {
MESSAGE_CONTENTS = (
[ 'start.welcome' ] = '歡迎使用 Docker Engine 安裝與換源腳本'
[ 'start.runtimeEnv' ] = '執行環境'
[ 'start.dateTime' ] = '系統時間'
[ 'end.moreInfo' ] = '腳本執行完畢,更多使用教學詳見官網'
[ 'end.sponsorAds' ] = '【贊助商廣告】'
[ 'error.cmd.options.needConfirm' ] = '請確認後重新輸入'
[ 'error.cmd.options.needSpecify' ] = '請在該選項後指定{}'
[ 'error.cmd.options.invalid' ] = '命令選項 {} 無效,{}! '
[ 'error.cmd.options.validAddress' ] = '有效的位址'
[ 'error.cmd.options.sourceAddress' ] = '軟體源位址'
[ 'error.cmd.options.registryAddress' ] = '映象倉庫位址'
[ 'error.cmd.options.sourceRepository' ] = '軟體源倉庫'
[ 'error.cmd.options.validVersion' ] = '有效的版本號'
[ 'error.cmd.options.ceRepositoryVersion' ] = 'Docker CE 軟體源倉庫的版本號'
[ 'error.cmd.options.version' ] = '版本號'
[ 'error.cmd.options.codename' ] = '版本代號'
[ 'error.cmd.options.boolean' ] = ' true 或 false '
[ 'error.cmd.options.protocol' ] = ' http 或 https '
[ 'error.cmd.options.needProtocol' ] = ' Web 協定(http/https)'
[ 'error.cmd.options.validLangKey' ] = '有效的語言 ID '
[ 'error.cmd.options.langKey' ] = '語言 ID '
[ 'error.unsupportSystem1' ] = '不支援當前作業系統({}) '
[ 'error.unsupportSystem2' ] = '不支援當前作業系統({}),請參考如下命令自行安裝:\n\n{}'
[ 'error.unknownSystem' ] = '未知系統'
[ 'error.unsupportX86_32' ] = 'Docker Engine 不支援安裝在 x86_32 架構的環境上!'
[ 'error.unknownArch' ] = '未知的系統架構:{}'
[ 'error.unsupportS390x' ] = '請查閱 RHEL 發行版宣告以瞭解 s390x 支援'
[ 'error.input' ] = '輸入錯誤,{}! '
[ 'error.needRoot' ] = '權限不足,請使用 Root 使用者執行本腳本'
[ 'error.sync' ] = '{}出錯,請先解決系統原有軟體源錯誤以確保 {} 軟體包管理工具可用!'
[ 'error.downloadGPG' ] = 'GPG 金鑰下載失敗,請檢查網路或更換 Docker CE 軟體源後重試!'
[ 'error.queryVersionFailed' ] = '查詢 Docker Engine 版本清單失敗!'
[ 'error.designatedVersion' ] = '指定的 Docker Engine 版本不存在或不支援安裝!'
[ 'error.invalidVersion' ] = '請輸入正確的版本號!'
[ 'error.reEnter' ] = '輸入錯誤請重新輸入!'
[ 'error.installDockerEngineFailed' ] = '安裝 Docker Engine 失敗!'
[ 'error.installPackageFailed' ] = '軟體包 {} 安裝失敗,請自行安裝後重新執行腳本!'
[ 'error.defaultBehavior.https' ] = '預設使用 HTTPS 協定'
[ 'error.defaultBehavior.noClose' ] = '預設不關閉'
[ 'error.defaultBehavior.installLatest' ] = '預設安裝最新版本'
[ 'error.defaultBehavior.noOverwrite' ] = '預設不覆寫'
[ 'error.defaultBehavior.noUseIntranetSource' ] = '預設不使用內網位址'
[ 'warn.usedCentosBranch' ] = '目前採用 centos 分支(紅帽衍生系統安裝方式)進行安裝,可能存在某些無法預料的相容性問題!'
[ 'warn.usedIntranetSource' ] = '已切換至內網專用位址,僅限在特定環境下使用!'
[ 'warn.needValidNumberIndex' ] = '請輸入有效的數字序號!'
[ 'warn.needInputNumberIndex' ] = '請輸入數字序號!'
[ 'warn.needManuallyDeleteConfig' ] = '請自行刪除 {} 中的 {} 設定並重新啟動服務 {}'
[ 'tip.unsupportRHEL10' ] = 'Docker 官方尚未支援 RHEL 10 且紅帽官方已將 Docker 從註冊軟體源中移除並預設使用 Podman。'
[ 'tip.skipInstallDockerEngine' ] = '偵測到系統已安裝 Docker Engine 且是最新版本,跳過安裝'
[ 'info.backuped.dockerConfig' ] = '已備份原有 Docker 設定檔'
[ 'interaction.source.type.public' ] = '公網'
[ 'interaction.source.type.intranet' ] = '內網'
[ 'interaction.source.type.select' ] = '請選擇 Docker CE 源的網路位址(存取方式): '
[ 'interaction.source.type.usePublicAddress' ] = '預設使用 Docker CE 源的公網位址,是否繼續'
[ 'interaction.source.dockerCE.select' ] = '請選擇你想使用的 Docker CE 源:'
[ 'interaction.source.dockerCE.selectAndInput' ] = '請選擇並輸入你想使用的 Docker CE 源'
[ 'interaction.source.dockerRegistry.select' ] = '請選擇你想使用的 Docker Registry 源:'
[ 'interaction.source.dockerRegistry.selectAndInput' ] = '請選擇並輸入你想使用的 Docker Registry 源'
[ 'interaction.protocol.select' ] = '請選擇 Docker CE 軟體源的網路協定:'
[ 'interaction.protocol.useHttp' ] = 'Docker CE 軟體源是否使用 HTTP 協定'
[ 'interaction.firewall.close' ] = '是否關閉系統防火牆和 SELinux '
[ 'interaction.install.selectVersion' ] = '請選擇你想安裝的版本:'
[ 'interaction.install.selectedVersion' ] = '指定安裝版本:'
[ 'interaction.install.selectedTitle' ] = '請選擇你要安裝的版本,如:{}'
[ 'interaction.install.inputVersion' ] = '請根據上面的清單,選擇並輸入你想要安裝的具體版本號:'
[ 'interaction.install.latestVersion' ] = 'Docker Engine 是否安裝最新版本'
[ 'interaction.backup.skipOverwrite' ] = '偵測到已備份的 Docker 設定檔,是否跳過覆寫備份'
[ 'interaction.common.tip' ] = '提示'
[ 'interaction.common.operationCanceled' ] = '操作已取消'
[ 'interaction.common.yes' ] = '是'
[ 'interaction.common.no' ] = '否'
[ 'work.installDependents' ] = '安裝環境軟體包'
[ 'work.installDockerEngine' ] = '安裝 Docker Engine'
[ 'source.sync.text1' ] = '更新軟體源'
[ 'source.sync.text2' ] = '產生軟體源快取'
[ 'result.install.failed' ] = '安裝失敗'
[ 'result.install.checkSourceFile' ] = '檢查源檔案:'
[ 'result.install.manuallyExecCmd' ] = '請嘗試手動執行安裝命令:{}'
[ 'result.install.notRunning' ] = '偵測到 Docker 服務啟動異常,可嘗試再次執行本腳本重試'
[ 'result.install.manuallyRun' ] = '請執行 {} 命令嘗試啟動或自行查詢錯誤原因'
[ 'result.registry.success' ] = '已更換映象倉庫'
[ 'result.registry.dockerEngineNotExsit' ] = '目前尚未安裝 Docker Engine, 請取消設定 {} 命令選項後重新執行腳本!'
[ 'commands.help' ] = ' 命令選項( 名稱/含義/值) :
--source 指定 Docker CE 軟體源位址( 網域名稱或IP) 位址
--source-registry 指定 Docker 映像倉庫位址 ( 網域名稱或IP) 位址
--branch 指定 Docker CE 軟體源倉庫 ( 路徑) 倉庫名稱
--branch-version 指定 Docker CE 軟體源倉庫版本 版本號
--designated-version 指定 Docker Engine 安裝版本 版本號
--codename 指定 Debian 係作業系統的版本代號 代號名稱
--protocol 指定 Docker CE 源的 Web 協定 http 或 https
--use-intranet-source 是否優先使用內部網路 Docker CE 軟體源位址 true 或 false
--install-latest 是否安裝最新版本的 Docker Engine true 或 false
--close-firewall 是否關閉防火牆 true 或 false
--clean-screen 是否在運行前清除螢幕上的所有內容 true 或 false
--lang 指定腳本輸出的語言 语言
--only-registry 僅更換映像倉庫模式 無
--ignore-backup-tips 忽略覆蓋備份提示 無
--pure-mode 純淨模式,精簡列印內容 無
--help 查看幫助選單 無
問題報告 { } '
[ 'mirrors.dockerCE.0' ] = '阿里雲'
[ 'mirrors.dockerCE.1' ] = '騰訊雲'
[ 'mirrors.dockerCE.2' ] = '華為雲'
[ 'mirrors.dockerCE.3' ] = '網易'
[ 'mirrors.dockerCE.4' ] = '火山引擎'
[ 'mirrors.dockerCE.5' ] = '微軟 Azure 中國'
[ 'mirrors.dockerCE.6' ] = '清華大學'
[ 'mirrors.dockerCE.7' ] = '北京大學'
[ 'mirrors.dockerCE.8' ] = '浙江大學'
[ 'mirrors.dockerCE.9' ] = '南京大學'
[ 'mirrors.dockerCE.10' ] = '上海交通大學'
[ 'mirrors.dockerCE.11' ] = '重慶郵電大學'
[ 'mirrors.dockerCE.12' ] = '中國科學技術大學'
[ 'mirrors.dockerCE.13' ] = '中國科學院軟體研究所'
[ 'mirrors.dockerCE.14' ] = '官方源'
[ 'mirrors.registry.0' ] = '毫秒鏡像(推薦)'
[ 'mirrors.registry.1' ] = 'Docker Proxy'
[ 'mirrors.registry.2' ] = 'DaoCloud 道客'
[ 'mirrors.registry.3' ] = '1Panel 鏡像'
[ 'mirrors.registry.4' ] = '阿里雲(杭州)'
[ 'mirrors.registry.5' ] = '阿里雲(上海)'
[ 'mirrors.registry.6' ] = '阿里雲(青島)'
[ 'mirrors.registry.7' ] = '阿里雲(北京)'
[ 'mirrors.registry.8' ] = '阿里雲(張家口)'
[ 'mirrors.registry.9' ] = '阿里雲(呼和浩特)'
[ 'mirrors.registry.10' ] = '阿里雲(烏蘭察布)'
[ 'mirrors.registry.11' ] = '阿里雲(深圳)'
[ 'mirrors.registry.12' ] = '阿里雲(河源)'
[ 'mirrors.registry.13' ] = '阿里雲(廣州)'
[ 'mirrors.registry.14' ] = '阿里雲(成都)'
[ 'mirrors.registry.15' ] = '阿里雲(香港)'
[ 'mirrors.registry.16' ] = '阿里雲(日本-東京)'
[ 'mirrors.registry.17' ] = '阿里雲(新加坡)'
[ 'mirrors.registry.18' ] = '阿里雲(馬來西亞-吉隆坡)'
[ 'mirrors.registry.19' ] = '阿里雲(印度尼西亞-雅加達)'
[ 'mirrors.registry.20' ] = '阿里雲(德國-法蘭克福)'
[ 'mirrors.registry.21' ] = '阿里雲(英國-倫敦)'
[ 'mirrors.registry.22' ] = '阿里雲(美國西部-矽谷)'
[ 'mirrors.registry.23' ] = '阿里雲(美國東部-弗吉尼亞)'
[ 'mirrors.registry.24' ] = '阿里雲(阿聯酋-迪拜)'
[ 'mirrors.registry.25' ] = '騰訊雲'
[ 'mirrors.registry.26' ] = '谷歌雲(北美)'
[ 'mirrors.registry.27' ] = '谷歌雲(亞洲)'
[ 'mirrors.registry.28' ] = '谷歌雲(歐洲)'
[ 'mirrors.registry.29' ] = '官方 Docker Hub'
)
SPONSOR_ADS[ 0] = "1Panel · 新一代的 Linux 伺服器維運管理面板 ➜ \033[3mhttps://1panel.cn\033[0m"
}
function msg_pack_en( ) {
MESSAGE_CONTENTS = (
[ 'start.welcome' ] = 'Docker installation & mirror switcher'
[ 'start.runtimeEnv' ] = 'Runtime Env'
[ 'start.dateTime' ] = 'System Time'
[ 'end.moreInfo' ] = 'Script execution completed, visit our website for more tutorials'
[ 'end.sponsorAds' ] = '[Sponsor Ads]'
[ 'error.cmd.options.needConfirm' ] = 'Please confirm and re-enter'
[ 'error.cmd.options.needSpecify' ] = 'Please specify {} after this option'
[ 'error.cmd.options.invalid' ] = 'Command option {} is invalid, {}!'
[ 'error.cmd.options.validAddress' ] = 'a valid address'
[ 'error.cmd.options.sourceAddress' ] = 'mirror address'
[ 'error.cmd.options.registryAddress' ] = 'registry mirror address'
[ 'error.cmd.options.sourceRepository' ] = 'mirror repository'
[ 'error.cmd.options.validVersion' ] = 'a valid version number'
[ 'error.cmd.options.ceRepositoryVersion' ] = 'Docker CE mirror repository version'
[ 'error.cmd.options.version' ] = 'version number'
[ 'error.cmd.options.codename' ] = 'version codename'
[ 'error.cmd.options.boolean' ] = ' true or false '
[ 'error.cmd.options.protocol' ] = ' http or https '
[ 'error.cmd.options.needProtocol' ] = ' Web protocol(http/https)'
[ 'error.cmd.options.validLangKey' ] = 'A valid language ID '
[ 'error.cmd.options.langKey' ] = 'language ID '
[ 'error.unsupportSystem1' ] = 'Unsupported operating system ({})'
[ 'error.unsupportSystem2' ] = 'Unsupported operating system ({}), please install manually with commands:'
[ 'error.unknownSystem' ] = 'Unknown system'
[ 'error.unsupportX86_32' ] = 'Docker Engine does not support installation on x86_32 architecture!'
[ 'error.unknownArch' ] = 'Unknown system architecture: {}'
[ 'error.unsupportS390x' ] = 'Please refer to RHEL distribution announcement for s390x support'
[ 'error.input' ] = 'Input error, {}!'
[ 'error.needRoot' ] = 'Insufficient permissions, please run this script as Root user'
[ 'error.sync' ] = '{} failed. Please fix system software sources (package repositories) so the {} package manager is available!'
[ 'error.downloadGPG' ] = 'GPG key download failed, please check network or switch Docker CE mirror and retry!'
[ 'error.queryVersionFailed' ] = 'Failed to query Docker Engine version list!'
[ 'error.designatedVersion' ] = 'Specified Docker Engine version does not exist or is not supported for installation!'
[ 'error.invalidVersion' ] = 'Please enter a valid version number!'
[ 'error.reEnter' ] = 'Input error, please re-enter!'
[ 'error.installDockerEngineFailed' ] = 'Docker Engine installation failed!'
[ 'error.installPackageFailed' ] = 'Package {} installation failed, please install manually and rerun script!'
[ 'error.defaultBehavior.https' ] = 'Using HTTPS protocol by default'
[ 'error.defaultBehavior.noClose' ] = 'Not closing by default'
[ 'error.defaultBehavior.installLatest' ] = 'Installing latest version by default'
[ 'error.defaultBehavior.noOverwrite' ] = 'Not overwriting by default'
[ 'error.defaultBehavior.noUseIntranetSource' ] = 'Not using intranet address by default'
[ 'warn.usedCentosBranch' ] = 'Currently using centos branch (Red Hat derivative OS installation method), may have unpredictable compatibility issues!'
[ 'warn.usedIntranetSource' ] = 'Switched to intranet-only address, use only in specific environments!'
[ 'warn.needValidNumberIndex' ] = 'Please enter a valid number index!'
[ 'warn.needInputNumberIndex' ] = 'Please enter a number index!'
[ 'warn.needManuallyDeleteConfig' ] = 'Please manually delete {} configuration in {} and restart service {}'
[ 'tip.unsupportRHEL10' ] = 'Docker official has not yet supported RHEL 10 and Red Hat has removed Docker from registered repositories, using Podman by default.'
[ 'tip.skipInstallDockerEngine' ] = 'Detected Docker Engine is already installed with latest version, skipping installation'
[ 'info.backuped.dockerConfig' ] = 'Original Docker config file has been backed up'
[ 'interaction.source.type.public' ] = 'Public'
[ 'interaction.source.type.intranet' ] = 'Intranet'
[ 'interaction.source.type.select' ] = 'Please select network address (access method) for Docker CE mirror:'
[ 'interaction.source.type.usePublicAddress' ] = 'Use public network address for Docker CE mirror by default, continue'
[ 'interaction.source.dockerCE.select' ] = 'Please select the Docker CE mirror you want to use:'
[ 'interaction.source.dockerCE.selectAndInput' ] = 'Please select and enter the Docker CE mirror you want to use'
[ 'interaction.source.dockerRegistry.select' ] = 'Please select the Docker Registry mirror you want to use:'
[ 'interaction.source.dockerRegistry.selectAndInput' ] = 'Please select and enter the Docker Registry mirror you want to use'
[ 'interaction.protocol.select' ] = 'Please select network protocol for Docker CE mirror:'
[ 'interaction.protocol.useHttp' ] = 'Use HTTP protocol for Docker CE mirror'
[ 'interaction.firewall.close' ] = 'Close system firewall and SELinux'
[ 'interaction.install.selectVersion' ] = 'Please select the version you want to install:'
[ 'interaction.install.selectedVersion' ] = 'Specified installation version:'
[ 'interaction.install.selectedTitle' ] = 'Please select the version to install, e.g.: {}'
[ 'interaction.install.inputVersion' ] = 'Based on the list above, please select and enter the specific version you want to install:'
[ 'interaction.install.latestVersion' ] = 'Install latest version of Docker Engine'
[ 'interaction.backup.skipOverwrite' ] = 'Detected existing backup of Docker config file, skip overwriting backup'
[ 'interaction.common.tip' ] = 'Tip'
[ 'interaction.common.operationCanceled' ] = 'Operation canceled'
[ 'interaction.common.yes' ] = 'Yes'
[ 'interaction.common.no' ] = 'No'
[ 'work.installDependents' ] = 'Install environment packages'
[ 'work.installDockerEngine' ] = 'Install Docker Engine'
[ 'source.sync.text1' ] = 'Update APT package index'
[ 'source.sync.text2' ] = 'Generate mirror cache'
[ 'result.install.failed' ] = 'Installation failed'
[ 'result.install.checkSourceFile' ] = 'Check source file:'
[ 'result.install.manuallyExecCmd' ] = 'Please try manually executing installation command: {}'
[ 'result.install.notRunning' ] = 'Detected Docker service startup error, try running this script again'
[ 'result.install.manuallyRun' ] = 'Please execute {} command to try starting or investigate error cause'
[ 'result.registry.success' ] = 'Registry mirror replaced successfully'
[ 'result.registry.dockerEngineNotExsit' ] = 'Docker Engine is not installed yet, please remove {} command option and rerun script!'
[ 'commands.help' ] = ' Command options( name/meaning/value) :
--source Specify Docker CE mirror address ( domain or IP) address
--source-registry Specify Docker Registry mirror address ( domain or IP) address
--branch Specify Docker CE mirror repository ( path) repo name
--branch-version Specify Docker CE mirror repository version version
--designated-version Specify Docker Engine installation version version
--codename Specify Debian-based OS codename codename
--protocol Specify Web protocol for Docker CE mirror http or https
--use-intranet-source Prefer intranet Docker CE mirror address true or false
--install-latest Whether to install the latest Docker Engine true or false
--close-firewall Whether to disable the firewall true or false
--clean-screen Whether to clear the screen before running true or false
--lang Specify the language of the script output language
--only-registry Only switch registry mirror mode none
--ignore-backup-tips Ignore backup overwrite prompt ( do not backup) none
--pure-mode Pure mode, minimal output none
--help Show help menu none
Issue Report { } '
[ 'mirrors.dockerCE.0' ] = 'Alibaba Cloud'
[ 'mirrors.dockerCE.1' ] = 'Tencent Cloud'
[ 'mirrors.dockerCE.2' ] = 'Huawei Cloud'
[ 'mirrors.dockerCE.3' ] = 'NetEase'
[ 'mirrors.dockerCE.4' ] = 'Volcengine'
[ 'mirrors.dockerCE.5' ] = 'Microsoft Azure China'
[ 'mirrors.dockerCE.6' ] = 'Tsinghua University'
[ 'mirrors.dockerCE.7' ] = 'Peking University'
[ 'mirrors.dockerCE.8' ] = 'Zhejiang University'
[ 'mirrors.dockerCE.9' ] = 'Nanjing University'
[ 'mirrors.dockerCE.10' ] = 'Shanghai Jiao Tong University'
[ 'mirrors.dockerCE.11' ] = 'Chongqing University of Posts and Telecommunications'
[ 'mirrors.dockerCE.12' ] = 'University of Science and Technology of China'
[ 'mirrors.dockerCE.13' ] = 'Institute of Software, Chinese Academy of Sciences'
[ 'mirrors.dockerCE.14' ] = 'Official Source'
[ 'mirrors.registry.0' ] = 'Millisecond Mirror (recommended)'
[ 'mirrors.registry.1' ] = 'Docker Proxy'
[ 'mirrors.registry.2' ] = 'DaoCloud'
[ 'mirrors.registry.3' ] = '1Panel Mirror'
[ 'mirrors.registry.4' ] = 'Alibaba Cloud (Hangzhou)'
[ 'mirrors.registry.5' ] = 'Alibaba Cloud (Shanghai)'
[ 'mirrors.registry.6' ] = 'Alibaba Cloud (Qingdao)'
[ 'mirrors.registry.7' ] = 'Alibaba Cloud (Beijing)'
[ 'mirrors.registry.8' ] = 'Alibaba Cloud (Zhangjiakou)'
[ 'mirrors.registry.9' ] = 'Alibaba Cloud (Hohhot)'
[ 'mirrors.registry.10' ] = 'Alibaba Cloud (Ulanqab)'
[ 'mirrors.registry.11' ] = 'Alibaba Cloud (Shenzhen)'
[ 'mirrors.registry.12' ] = 'Alibaba Cloud (Heyuan)'
[ 'mirrors.registry.13' ] = 'Alibaba Cloud (Guangzhou)'
[ 'mirrors.registry.14' ] = 'Alibaba Cloud (Chengdu)'
[ 'mirrors.registry.15' ] = 'Alibaba Cloud (Hong Kong)'
[ 'mirrors.registry.16' ] = 'Alibaba Cloud (Japan - Tokyo)'
[ 'mirrors.registry.17' ] = 'Alibaba Cloud (Singapore)'
[ 'mirrors.registry.18' ] = 'Alibaba Cloud (Malaysia - Kuala Lumpur)'
[ 'mirrors.registry.19' ] = 'Alibaba Cloud (Indonesia - Jakarta)'
[ 'mirrors.registry.20' ] = 'Alibaba Cloud (Germany - Frankfurt)'
[ 'mirrors.registry.21' ] = 'Alibaba Cloud (UK - London)'
[ 'mirrors.registry.22' ] = 'Alibaba Cloud (US West - Silicon Valley)'
[ 'mirrors.registry.23' ] = 'Alibaba Cloud (US East - Virginia)'
[ 'mirrors.registry.24' ] = 'Alibaba Cloud (UAE - Dubai)'
[ 'mirrors.registry.25' ] = 'Tencent Cloud'
[ 'mirrors.registry.26' ] = 'Google Cloud (North America)'
[ 'mirrors.registry.27' ] = 'Google Cloud (Asia)'
[ 'mirrors.registry.28' ] = 'Google Cloud (Europe)'
[ 'mirrors.registry.29' ] = 'Official Docker Hub'
)
SPONSOR_ADS = (
"1Panel · Top-Rated Web-based Linux Server Management Tool ➜ \033[3mhttps://1panel.cn\033[0m"
)
}
init_msg_pack
2024-07-25 10:21:28 +08:00
handle_command_options " $@ "
main