Files
qwsy/月度/11月/晨午检脚本/tomcat.sh
binghuai 2430c0e683 11.20
2025-11-20 19:01:30 +08:00

616 lines
19 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 配置区域 - 便于修改
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 "$@"