616 lines
19 KiB
Bash
616 lines
19 KiB
Bash
#!/bin/bash
|
||
|
||
# 配置区域 - 便于修改
|
||
readonly TOMCAT_PORTS=(90107 90108)
|
||
readonly TOMCAT_BASE_PATH="/home/chenwujian2"
|
||
readonly DIST_PATH="/home/stxt/cwj2/"
|
||
readonly CONFIG_SOURCE_PATH="/home/chenwujian/tomcat90105/webapps"
|
||
readonly CLEANUP_PATHS=(
|
||
"/home/chenwujian2/script/2025/"
|
||
"/home/chenwujian2/script/logs/app.log"
|
||
)
|
||
|
||
# 颜色定义
|
||
readonly RED='\033[0;31m'
|
||
readonly GREEN='\033[0;32m'
|
||
readonly YELLOW='\033[1;33m'
|
||
readonly BLUE='\033[0;34m'
|
||
readonly CYAN='\033[0;36m'
|
||
readonly PURPLE='\033[0;35m'
|
||
readonly NC='\033[0m' # No Color
|
||
|
||
# 获取Tomcat完整路径
|
||
get_tomcat_path() {
|
||
local port=$1
|
||
echo "${TOMCAT_BASE_PATH}/tomcat${port}"
|
||
}
|
||
|
||
# 日志函数
|
||
log() {
|
||
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
|
||
}
|
||
|
||
warn() {
|
||
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] 警告: $1${NC}"
|
||
}
|
||
|
||
error() {
|
||
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] 错误: $1${NC}"
|
||
}
|
||
|
||
info() {
|
||
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
|
||
}
|
||
|
||
# 显示菜单
|
||
show_menu() {
|
||
clear
|
||
echo -e "${CYAN}"
|
||
echo "================================================"
|
||
echo " Tomcat 服务管理菜单"
|
||
echo "================================================"
|
||
echo -e "${NC}"
|
||
echo -e "${GREEN}1. 启动 Tomcat 服务${NC}"
|
||
echo -e "${GREEN}2. 停止 Tomcat 服务${NC}"
|
||
echo -e "${GREEN}3. 重启 Tomcat 服务${NC}"
|
||
echo -e "${YELLOW}4. 部署应用到 Tomcat${NC}"
|
||
echo -e "${YELLOW}5. 分发配置文件${NC}"
|
||
echo -e "${BLUE}6. 查看服务状态${NC}"
|
||
echo -e "${PURPLE}7. 查看 Tomcat 日志${NC}"
|
||
echo -e "${RED}8. 清理所有文件(包括日志)${NC}"
|
||
echo -e "${RED}9. 仅清理 Tomcat 日志${NC}"
|
||
echo -e "${CYAN}a. 完整部署流程${NC}"
|
||
echo -e "${RED}0. 退出脚本${NC}"
|
||
echo "================================================"
|
||
}
|
||
|
||
# 检查必要目录是否存在
|
||
check_dependencies() {
|
||
if [ ! -d "$TOMCAT_BASE_PATH" ]; then
|
||
error "基础路径不存在: $TOMCAT_BASE_PATH"
|
||
return 1
|
||
fi
|
||
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
if [ ! -d "$tomcat_path" ]; then
|
||
error "Tomcat实例路径不存在: $tomcat_path"
|
||
return 1
|
||
fi
|
||
done
|
||
|
||
return 0
|
||
}
|
||
|
||
# 显示Tomcat日志(实时输出)
|
||
show_tomcat_logs() {
|
||
local port=$1
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
local log_file="${tomcat_path}/logs/catalina.out"
|
||
|
||
if [ ! -f "$log_file" ]; then
|
||
warn "日志文件不存在: $log_file"
|
||
echo "可能的原因:"
|
||
echo "1. Tomcat 尚未启动"
|
||
echo "2. 日志文件路径不正确"
|
||
echo "3. 没有读取权限"
|
||
return 1
|
||
fi
|
||
|
||
info "开始显示 Tomcat $port 日志 (按 Ctrl+C 退出)..."
|
||
echo -e "${CYAN}================================================${NC}"
|
||
echo -e "${CYAN}日志文件: $log_file${NC}"
|
||
echo -e "${CYAN}================================================${NC}"
|
||
|
||
# 显示文件大小
|
||
local file_size=$(du -h "$log_file" | cut -f1)
|
||
echo -e "${BLUE}日志文件大小: $file_size${NC}"
|
||
echo ""
|
||
|
||
# 使用 trap 来捕获 Ctrl+C 信号
|
||
trap 'kill $tail_pid $stat_pid 2>/dev/null; echo ""; info "已退出日志查看"; exit 0' INT TERM
|
||
|
||
# 显示最后50行日志,然后实时跟踪新日志
|
||
tail -n 50 -f "$log_file" &
|
||
local tail_pid=$!
|
||
|
||
# 等待 tail 进程结束
|
||
wait $tail_pid 2>/dev/null
|
||
trap - INT TERM # 清理 trap
|
||
}
|
||
|
||
# 查看日志菜单
|
||
view_logs_menu() {
|
||
local choice
|
||
while true; do
|
||
clear
|
||
echo -e "${PURPLE}"
|
||
echo "================================================"
|
||
echo " 查看 Tomcat 日志"
|
||
echo "================================================"
|
||
echo -e "${NC}"
|
||
|
||
# 显示各Tomcat状态
|
||
for i in "${!TOMCAT_PORTS[@]}"; do
|
||
local port="${TOMCAT_PORTS[$i]}"
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
local log_file="${tomcat_path}/logs/catalina.out"
|
||
|
||
if [ -f "$log_file" ]; then
|
||
local file_size=$(du -h "$log_file" | cut -f1)
|
||
local line_count=$(wc -l < "$log_file" 2>/dev/null || echo "0")
|
||
echo -e "${CYAN}$((i+1)). Tomcat $port 日志${NC}"
|
||
echo -e " 文件: $log_file"
|
||
echo -e " 大小: $file_size, 行数: $line_count"
|
||
else
|
||
echo -e "${YELLOW}$((i+1)). Tomcat $port 日志${NC}"
|
||
echo -e " 状态: ${RED}日志文件不存在${NC}"
|
||
fi
|
||
echo ""
|
||
done
|
||
|
||
echo -e "${CYAN}c. 查看所有 Tomcat 日志(多窗口)${NC}"
|
||
echo -e "${CYAN}b. 返回主菜单${NC}"
|
||
echo "================================================"
|
||
|
||
read -p "请选择要查看的日志 (1-${#TOMCAT_PORTS[@]}/c/b): " choice
|
||
|
||
case $choice in
|
||
[1-9])
|
||
local index=$((choice-1))
|
||
if [ $index -lt ${#TOMCAT_PORTS[@]} ]; then
|
||
local port="${TOMCAT_PORTS[$index]}"
|
||
show_tomcat_logs "$port"
|
||
read -p "按回车键继续..." dummy
|
||
else
|
||
error "无效选择,请重新输入!"
|
||
sleep 1
|
||
fi
|
||
;;
|
||
c|C)
|
||
view_all_logs
|
||
;;
|
||
b|B)
|
||
return
|
||
;;
|
||
*)
|
||
error "无效选择,请重新输入!"
|
||
sleep 1
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
# 查看所有Tomcat日志(多窗口方式)
|
||
view_all_logs() {
|
||
info "即将在新窗口中打开所有Tomcat日志..."
|
||
echo "这将为每个Tomcat打开一个独立的终端窗口查看日志"
|
||
echo "关闭日志窗口后,按回车键返回菜单"
|
||
echo ""
|
||
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
local log_file="${tomcat_path}/logs/catalina.out"
|
||
|
||
if [ -f "$log_file" ]; then
|
||
info "为 Tomcat $port 打开日志窗口..."
|
||
# 使用 gnome-terminal, xterm 或 screen 来打开新窗口
|
||
if command -v gnome-terminal >/dev/null 2>&1; then
|
||
gnome-terminal --title="Tomcat $port 日志" -- bash -c "echo '正在显示 Tomcat $port 日志...'; echo '文件: $log_file'; echo '按 Ctrl+C 退出'; echo '================================'; tail -n 50 -f '$log_file'; exec bash"
|
||
elif command -v xterm >/dev/null 2>&1; then
|
||
xterm -title "Tomcat $port 日志" -e bash -c "echo '正在显示 Tomcat $port 日志...'; echo '文件: $log_file'; echo '按 Ctrl+C 退出'; echo '================================'; tail -n 50 -f '$log_file'; read -p '按回车键关闭...'"
|
||
else
|
||
warn "未找到可用的终端程序,无法打开多窗口"
|
||
info "将在当前终端依次显示日志..."
|
||
show_tomcat_logs "$port"
|
||
fi
|
||
else
|
||
warn "Tomcat $port 日志文件不存在: $log_file"
|
||
fi
|
||
done
|
||
|
||
read -p "所有日志窗口已启动,按回车键返回菜单..." dummy
|
||
}
|
||
|
||
# 启动Tomcat并显示日志
|
||
start_tomcats_with_logs() {
|
||
log "启动Tomcat服务..."
|
||
|
||
# 首先启动所有Tomcat
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
if [ -f "${tomcat_path}/bin/startup.sh" ]; then
|
||
info "启动Tomcat $port..."
|
||
if sh "${tomcat_path}/bin/startup.sh"; then
|
||
log "Tomcat $port 启动命令执行完成"
|
||
else
|
||
error "Tomcat $port 启动失败"
|
||
fi
|
||
else
|
||
error "启动脚本不存在: ${tomcat_path}/bin/startup.sh"
|
||
fi
|
||
done
|
||
|
||
# 等待一段时间让Tomcat开始启动
|
||
info "等待Tomcat启动..."
|
||
sleep 5
|
||
|
||
# 显示启动状态
|
||
show_tomcat_status
|
||
|
||
# 询问是否查看日志
|
||
echo
|
||
read -p "是否查看Tomcat启动日志?(y/n, 默认y): " view_logs
|
||
view_logs=${view_logs:-y}
|
||
|
||
if [[ $view_logs =~ ^[Yy]$ ]]; then
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
echo
|
||
read -p "是否查看 Tomcat $port 的启动日志?(y/n): " view_single
|
||
if [[ $view_single =~ ^[Yy]$ ]]; then
|
||
show_tomcat_logs "$port"
|
||
fi
|
||
done
|
||
fi
|
||
}
|
||
|
||
# 清理Tomcat日志
|
||
clean_tomcat_logs() {
|
||
log "开始清理Tomcat日志..."
|
||
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
local logs_path="${tomcat_path}/logs"
|
||
|
||
if [ -d "$logs_path" ]; then
|
||
info "清理Tomcat $port 日志..."
|
||
|
||
# 清理catalina.out(清空内容而不是删除文件)
|
||
if [ -f "${logs_path}/catalina.out" ]; then
|
||
> "${logs_path}/catalina.out"
|
||
log "Tomcat $port - 已清空 catalina.out"
|
||
fi
|
||
|
||
# 删除旧的日志文件,但保留最近的一些
|
||
local log_files=("catalina." "localhost." "manager." "host-manager." "localhost_access_log.")
|
||
|
||
for log_prefix in "${log_files[@]}"; do
|
||
# 删除7天前的日志文件
|
||
find "$logs_path" -name "${log_prefix}*" -type f -mtime +7 -delete 2>/dev/null
|
||
|
||
# 统计清理结果
|
||
local remaining_count=$(find "$logs_path" -name "${log_prefix}*" -type f | wc -l)
|
||
log "Tomcat $port - ${log_prefix}* 剩余文件: $remaining_count"
|
||
done
|
||
|
||
# 清理temp目录
|
||
local temp_path="${tomcat_path}/temp"
|
||
if [ -d "$temp_path" ]; then
|
||
rm -rf "${temp_path}"/*
|
||
log "Tomcat $port - 已清空 temp 目录"
|
||
fi
|
||
else
|
||
warn "Tomcat $port 日志路径不存在: $logs_path"
|
||
fi
|
||
done
|
||
}
|
||
|
||
# 清理文件函数
|
||
cleanup_files() {
|
||
log "开始清理文件..."
|
||
|
||
for path in "${CLEANUP_PATHS[@]}"; do
|
||
if [[ "$path" == */ ]]; then
|
||
# 如果是目录,删除目录下所有文件但保留目录
|
||
if [ -d "$path" ]; then
|
||
rm -rf "${path}"*
|
||
log "已清空目录: $path"
|
||
else
|
||
warn "目录不存在: $path"
|
||
fi
|
||
else
|
||
# 如果是文件,清空内容或删除
|
||
if [ -f "$path" ]; then
|
||
> "$path" # 清空文件内容
|
||
log "已清空文件: $path"
|
||
else
|
||
warn "文件不存在: $path"
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# 清理Tomcat日志
|
||
clean_tomcat_logs
|
||
}
|
||
|
||
# 启动Tomcat
|
||
start_tomcats() {
|
||
log "启动Tomcat服务..."
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
if [ -f "${tomcat_path}/bin/startup.sh" ]; then
|
||
info "启动Tomcat $port..."
|
||
if sh "${tomcat_path}/bin/startup.sh"; then
|
||
log "Tomcat $port 启动完成"
|
||
else
|
||
error "Tomcat $port 启动失败"
|
||
fi
|
||
else
|
||
error "启动脚本不存在: ${tomcat_path}/bin/startup.sh"
|
||
fi
|
||
done
|
||
show_tomcat_status
|
||
}
|
||
|
||
# 停止Tomcat(精确停止指定端口的Tomcat)
|
||
stop_tomcats() {
|
||
log "停止Tomcat服务..."
|
||
|
||
# 首先使用正常关闭方式
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
if [ -f "${tomcat_path}/bin/shutdown.sh" ]; then
|
||
info "停止Tomcat $port..."
|
||
if sh "${tomcat_path}/bin/shutdown.sh"; then
|
||
log "Tomcat $port 已发送停止命令"
|
||
else
|
||
warn "Tomcat $port 停止过程中可能出现问题"
|
||
fi
|
||
else
|
||
error "停止脚本不存在: ${tomcat_path}/bin/shutdown.sh"
|
||
fi
|
||
done
|
||
|
||
# 等待正常关闭
|
||
info "等待正常关闭..."
|
||
sleep 5
|
||
|
||
# 精确杀死指定端口的进程
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
# 查找监听指定端口的Java进程
|
||
local pids=$(netstat -tlnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f1 | grep -v '^-$' | grep -v '^$')
|
||
if [ -n "$pids" ]; then
|
||
warn "发现端口 $port 的残留进程,强制杀死: $pids"
|
||
kill -9 $pids 2>/dev/null
|
||
fi
|
||
|
||
# 另外通过进程参数查找对应的Tomcat进程
|
||
local tomcat_pids=$(ps -ef | grep java | grep "catalina.base=/home/chenwujian2/tomcat${port}" | grep -v grep | awk '{print $2}')
|
||
if [ -n "$tomcat_pids" ]; then
|
||
warn "发现Tomcat${port}的残留进程,强制杀死: $tomcat_pids"
|
||
kill -9 $tomcat_pids 2>/dev/null
|
||
fi
|
||
done
|
||
|
||
show_tomcat_status
|
||
}
|
||
|
||
# 重启Tomcat
|
||
restart_tomcats() {
|
||
log "重启Tomcat服务..."
|
||
stop_tomcats
|
||
sleep 2
|
||
start_tomcats_with_logs
|
||
}
|
||
|
||
# 分发配置文件
|
||
distribute_config() {
|
||
log "分发配置文件..."
|
||
|
||
if [ ! -d "$CONFIG_SOURCE_PATH" ]; then
|
||
error "配置文件源路径不存在: $CONFIG_SOURCE_PATH"
|
||
return 1
|
||
fi
|
||
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
local target_path="${tomcat_path}/webapps/ROOT/WEB-INF/classes"
|
||
|
||
# 创建目标目录(如果不存在)
|
||
mkdir -p "${target_path}/properties"
|
||
|
||
# 复制配置文件
|
||
if \cp -rf "${CONFIG_SOURCE_PATH}/jeeplus.properties" "${target_path}/properties/"; then
|
||
log "Tomcat $port - jeeplus.properties 复制完成"
|
||
else
|
||
error "Tomcat $port - jeeplus.properties 复制失败"
|
||
fi
|
||
|
||
if \cp -rf "${CONFIG_SOURCE_PATH}/fdfs_client.conf" "${target_path}/"; then
|
||
log "Tomcat $port - fdfs_client.conf 复制完成"
|
||
else
|
||
error "Tomcat $port - fdfs_client.conf 复制失败"
|
||
fi
|
||
done
|
||
}
|
||
|
||
# 显示Tomcat状态
|
||
show_tomcat_status() {
|
||
log "Tomcat进程状态:"
|
||
|
||
# 精确显示指定Tomcat的进程(通过catalina.base路径匹配)
|
||
local found_process=0
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
local process=$(ps -ef | grep java | grep "catalina.base=${tomcat_path}" | grep -v grep)
|
||
if [ -n "$process" ]; then
|
||
echo -e "${GREEN}Tomcat $port 运行中:${NC}"
|
||
echo -e "${GREEN}$process${NC}"
|
||
echo ""
|
||
found_process=1
|
||
else
|
||
echo -e "${YELLOW}Tomcat $port: 未运行${NC}"
|
||
echo ""
|
||
fi
|
||
done
|
||
|
||
if [ $found_process -eq 0 ]; then
|
||
info "所有指定的Tomcat实例均未运行"
|
||
fi
|
||
|
||
# 显示端口占用情况(更精确的端口检测)
|
||
log "端口占用情况:"
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
# 使用更精确的端口检测
|
||
if ss -tlnp 2>/dev/null | grep ":${port} " >/dev/null || \
|
||
netstat -tlnp 2>/dev/null | grep ":${port} " >/dev/null; then
|
||
# 获取占用该端口的进程信息
|
||
local port_info=""
|
||
if command -v ss >/dev/null 2>&1; then
|
||
port_info=$(ss -tlnp | grep ":${port} " | head -1)
|
||
local pid=$(echo "$port_info" | grep -o 'pid=[0-9]*' | cut -d= -f2)
|
||
else
|
||
port_info=$(netstat -tlnp 2>/dev/null | grep ":${port} " | head -1)
|
||
local pid=$(echo "$port_info" | awk '{print $7}' | cut -d'/' -f1)
|
||
fi
|
||
|
||
if [ -n "$pid" ] && [ "$pid" != "-" ]; then
|
||
# 检查该进程是否是我们管理的Tomcat
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
if ps -p "$pid" -o command= 2>/dev/null | grep -q "catalina.base=${tomcat_path}"; then
|
||
echo -e "${GREEN}端口 $port: 被本脚本管理的Tomcat占用 (PID: $pid)${NC}"
|
||
else
|
||
echo -e "${YELLOW}端口 $port: 被其他进程占用 (PID: $pid)${NC}"
|
||
fi
|
||
else
|
||
echo -e "${YELLOW}端口 $port: 被占用 (无法获取PID)${NC}"
|
||
fi
|
||
else
|
||
echo -e "${RED}端口 $port: 未被占用${NC}"
|
||
fi
|
||
done
|
||
}
|
||
|
||
# 部署应用
|
||
deploy_app() {
|
||
log "开始部署应用..."
|
||
local today=$(date +"%Y%m%d%H%M")
|
||
|
||
if [ ! -f "${DIST_PATH}ROOT.tar.gz" ]; then
|
||
error "部署包不存在: ${DIST_PATH}ROOT.tar.gz"
|
||
return 1
|
||
fi
|
||
|
||
for port in "${TOMCAT_PORTS[@]}"; do
|
||
local tomcat_path=$(get_tomcat_path "$port")
|
||
local webapps_path="${tomcat_path}/webapps"
|
||
|
||
# 停止当前Tomcat
|
||
info "停止Tomcat $port..."
|
||
sh "${tomcat_path}/bin/shutdown.sh" 2>/dev/null
|
||
sleep 2
|
||
|
||
# 清理旧应用
|
||
rm -f "${webapps_path}/ROOT.tar.gz"
|
||
rm -rf "${webapps_path}/ROOT"
|
||
|
||
# 部署新应用
|
||
if cp "${DIST_PATH}ROOT.tar.gz" "${webapps_path}/"; then
|
||
if tar -zxf "${webapps_path}/ROOT.tar.gz" -C "${webapps_path}/"; then
|
||
log "Tomcat $port 部署完成"
|
||
else
|
||
error "Tomcat $port 解压失败"
|
||
fi
|
||
else
|
||
error "Tomcat $port 复制部署包失败"
|
||
fi
|
||
done
|
||
|
||
# 备份部署包
|
||
if mv "${DIST_PATH}/ROOT.tar.gz" "${DIST_PATH}/ROOT.${today}.tar.gz"; then
|
||
log "部署包已备份: ${DIST_PATH}/ROOT.${today}.tar.gz"
|
||
else
|
||
error "部署包备份失败"
|
||
fi
|
||
}
|
||
|
||
# 完整流程
|
||
full_process() {
|
||
log "开始执行完整流程..."
|
||
cleanup_files
|
||
stop_tomcats
|
||
deploy_app
|
||
distribute_config
|
||
start_tomcats_with_logs
|
||
log "完整流程执行完毕!"
|
||
}
|
||
|
||
# 执行选择的操作
|
||
execute_choice() {
|
||
local choice=$1
|
||
|
||
case $choice in
|
||
1)
|
||
start_tomcats_with_logs
|
||
;;
|
||
2)
|
||
stop_tomcats
|
||
;;
|
||
3)
|
||
restart_tomcats
|
||
;;
|
||
4)
|
||
deploy_app
|
||
read -p "部署完成,是否启动Tomcat服务?(y/n, 默认y): " start_after_deploy
|
||
start_after_deploy=${start_after_deploy:-y}
|
||
if [[ $start_after_deploy =~ ^[Yy]$ ]]; then
|
||
start_tomcats_with_logs
|
||
fi
|
||
;;
|
||
5)
|
||
distribute_config
|
||
;;
|
||
6)
|
||
show_tomcat_status
|
||
;;
|
||
7)
|
||
view_logs_menu
|
||
;;
|
||
8)
|
||
cleanup_files
|
||
;;
|
||
9)
|
||
clean_tomcat_logs
|
||
;;
|
||
a|A)
|
||
full_process
|
||
;;
|
||
0)
|
||
log "再见!"
|
||
exit 0
|
||
;;
|
||
*)
|
||
error "无效选择,请重新输入!"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# 主函数
|
||
main() {
|
||
# 检查依赖
|
||
if ! check_dependencies; then
|
||
error "环境检查失败,请检查配置"
|
||
exit 1
|
||
fi
|
||
|
||
while true; do
|
||
show_menu
|
||
echo
|
||
read -p "请选择操作 (0-9/a): " choice
|
||
|
||
case $choice in
|
||
[0-9aA])
|
||
execute_choice "$choice"
|
||
;;
|
||
*)
|
||
error "无效输入,请输入数字 0-9 或 a"
|
||
;;
|
||
esac
|
||
|
||
echo
|
||
read -p "按回车键继续..." dummy
|
||
done
|
||
}
|
||
|
||
# 脚本入口
|
||
main "$@" |