linux 脚本解释

if [ $? -ne 0 ]; then

echo "错误: 无法关闭现有 Tomcat 实例,终止启动流程!" >&2

exit 1

fi

  1. $? 是shell中的特殊变量,表示上一个命令的退出状态码
  2. -ne 0 表示"不等于0"(在Unix/Linux中,0通常表示成功,非0表示错误)
  3. 如果前一个命令执行失败(返回非0),则执行花括号内的内容:
    • 输出错误信息到标准错误输出(stderr)
    • 使用exit 1终止脚本执行并返回错误状态码1

--------------------------------------------------------------------------------------------------

if [ -z "$1" ]; then
echo "用法: $0 <TOMCAT_DIRECTORY>"
exit 1
fi

具体解释如下:

  1. if [ -z "$1" ] 检查第一个参数($1)是否为空字符串

    • -z 测试字符串长度是否为0
    • $1 表示脚本的第一个参数
  2. 如果参数为空(即用户没有提供参数),则:

    • 输出用法提示:echo "用法: $0 <TOMCAT_DIRECTORY>"
      • $0 表示当前脚本的名称
    • 以状态码1退出脚本:exit 1 (1通常表示错误退出)

---------------------------------------------------------------------------------------------------

TOMCAT_DIR="$1"
TIMEOUT=10
TOMCAT=$(basename "${TOMCAT_DIR}")
CURRENT_USER=$(whoami)

以下是详细解释:

  1. TOMCAT_DIR="$1"

    • 将脚本的第一个参数($1)赋值给变量TOMCAT_DIR
    • 这个参数应该是Tomcat的安装目录路径
  2. TIMEOUT=10

    • 设置超时时间为10秒
    • 用于后续等待Tomcat关闭的时间控制
  3. TOMCAT=$(basename "${TOMCAT_DIR}")

    • 使用basename命令从目录路径中提取最后一级目录名
    • 例如:如果TOMCAT_DIR/opt/apache-tomcat-9.0.45,则TOMCAT值为apache-tomcat-9.0.45
  4. CURRENT_USER=$(whoami)

    • 获取当前执行脚本的用户名
    • 用于后续的权限检查和日志记录

-------------------------------------------------------------------------------------------------------------

# 检查目录和脚本存在性
[ ! -d "${TOMCAT_DIR}" ] && echo "错误: 目录不存在" && exit 1
[ ! -x "${TOMCAT_DIR}/bin/shutdown.sh" ] && echo "错误: shutdown.sh 不可执行" && exit 1

# 获取 Tomcat 主进程 PID(精确匹配)
get_pids() {
ps -ef | grep "${TOMCAT}" | grep "org.apache.catalina.startup.Bootstrap" | grep -v grep | awk '{print $2}'
}

详细解释它们的功能和实现原理:

  1. 目录和脚本存在性检查部分:

    • [ ! -d "${TOMCAT_DIR}" ]:检查指定的Tomcat目录是否存在
      • -d测试目录是否存在
      • !表示逻辑非
    • [ ! -x "${TOMCAT_DIR}/bin/shutdown.sh" ]:检查shutdown.sh脚本是否存在且可执行
      • -x测试文件是否存在且可执行
    • 如果任一检查失败,会输出错误信息并以状态码1退出
  2. 获取Tomcat进程PID的函数:

    • ps -ef:列出所有进程的完整信息
    • grep "${TOMCAT}":过滤包含Tomcat目录名的进程
    • grep "org.apache.catalina.startup.Bootstrap":精确匹配Tomcat主类
    • grep -v grep:排除grep命令自身的进程
    • awk '{print $2}':提取第二列(即PID)
    • 这个函数通过多级过滤确保只获取真正的Tomcat主进程PID

----------------------------------------------------------------------------------------------------------------

# 初始检查进程
PIDS=$(get_pids)
if [ -z "${PIDS}" ]; then
echo "Tomcat 未运行,无需关闭"
exit 0
fi

echo "检测到 Tomcat 进程 (PID: ${PIDS})"

# 步骤1:尝试优雅关闭(忽略非关键错误,但记录)
echo "尝试优雅关闭..."
if ! ${TOMCAT_DIR}/bin/shutdown.sh; then
echo "警告: shutdown.sh 执行失败(可能权限不足)"
fi

# 等待优雅关闭
echo "等待 ${TIMEOUT} 秒..."
sleep ${TIMEOUT}

详细解析:

  1. 初始进程检查:

    • 调用get_pids函数获取Tomcat进程PID
    • 如果PID为空(-z测试),输出提示并正常退出(exit 0)
    • 否则显示检测到的进程PID
  2. 优雅关闭流程:

    • 首先尝试执行Tomcat的shutdown.sh脚本
    • 使用if ! command结构捕获执行失败情况
    • 即使失败也仅输出警告而不终止(因为后续还有强制关闭逻辑)
  3. 等待处理:

    • 使用sleep命令等待预设的TIMEOUT时间(之前定义为10秒)
    • 这是给Tomcat完成正常关闭流程的时间窗口

----------------------------------------------------------------------------------------------------------

# 步骤2:检查是否仍有进程
PIDS=$(get_pids)
if [ -n "${PIDS}" ]; then
echo "尝试正常终止进程 (PID: ${PIDS})"
# 逐个检查并终止进程,记录失败
for pid in ${PIDS}; do
# 检查进程所有者
PROCESS_OWNER=$(ps -o user= -p "${pid}" 2>/dev/null || echo "unknown")
echo "进程 ${pid} 所有者: ${PROCESS_OWNER}"

# 尝试终止进程
if ! kill "${pid}" 2>/dev/null; then
echo "错误: 无法终止进程 ${pid}(权限不足,当前用户 ${CURRENT_USER} 无法操作 ${PROCESS_OWNER} 的进程)"
exit 1  # 权限不足时立即报错退出
fi
done

    # 等待后再次检查
sleep 5
PIDS=$(get_pids)
if [ -n "${PIDS}" ]; then
echo "尝试强制终止进程 (PID: ${PIDS})"
for pid in ${PIDS}; do
if ! kill -9 "${pid}" 2>/dev/null; then
echo "错误: 无法强制终止进程 ${pid}(权限不足)"
exit 1  # 权限不足时立即报错退出
fi
done
fi
fi

# 最终检查
PIDS=$(get_pids)
if [ -z "${PIDS}" ]; then
echo "Tomcat 已成功关闭"
else
echo "错误: 仍有进程未关闭 (PID: ${PIDS})"
exit 1
fi

echo "========== 关闭完成 =========="
exit 0

详细解析:

  1. 进程二次检查:

    • 使用-n测试检查是否仍有存活的Tomcat进程
    • 如果有则进入强制终止流程
  2. 分级终止策略:

    • 先尝试普通kill命令(SIGTERM信号)
    • 检查每个进程的所有者(使用ps -o user= -p PID)
    • 对kill失败的情况立即报错退出(权限问题)
  3. 强制终止阶段:

    • 等待5秒后再次检查
    • 对仍然存活的进程使用kill -9(SIGKILL信号)
    • 同样处理权限错误情况
  4. 最终状态确认:

    • 最后一次检查进程状态
    • 根据结果输出成功/失败信息
    • 返回相应的退出状态码(0成功/1失败)

这个设计体现了完善的进程管理策略:

  • 分级处理(先优雅后强制)
  • 完善的错误检查和权限验证
  • 明确的进程状态跟踪
  • 清晰的执行反馈

代码中几个关键Shell技巧:

  • 2>/dev/null屏蔽错误输出
  • ps -o user=只输出用户名列
  • || echo "unknown"错误处理
  • 多级if [ -n/-z ]条件测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/news/915115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Glary Utilities(系统优化工具) v6.20.0.24 专业便携版

GlaryUtilities 允许你清理系统垃圾文件&#xff0c;无效的注册表&#xff0c;上网记录&#xff0c;删除插件&#xff0c;查找重复文件&#xff0c;优化内存&#xff0c;修理或删除快捷方式&#xff0c;管理windows启动程序&#xff0c;卸载软件&#xff0c;安全删除文件&#…

VScode链接服务器一直卡在下载vscode服务器/scp上传服务器,无法连接成功

终极方案&#xff08;强力推荐&#xff0c;亲测有效&#xff0c;链接只需5秒钟&#xff09;&#xff1a;本地下载复制到mkdir -p ~/.vscode-server/bin/<commit_hash>里面 <commit_hash>可以从帮助->关于里面找到&#xff0c;如下所示 版本: 1.96.2 提交: fa…

基于Spring Boot的农村农产品销售系统设计与实现

随着现代农业的快速发展,传统农产品的销售模式逐渐暴露出信息闭塞、流通效率低和中间环节多等问题。为了打破这些瓶颈,我基于Spring Boot框架开发了一套农产品销售系统,旨在构建一座连接农民与消费者之间的数字桥梁,让优质农产品更高效地直达用户餐桌。 一、项目背景与目标…

Mysql默认存储引擎InnoDB和底层数据结构

在黑马点评项目实战中&#xff1a;谈到了为什么不推荐使用mysql的字段自增作为订单id传递给客户端&#xff0c;让我想到了Mysql的​​存储引擎​​和​​底层数据结构​​究竟是什么&#xff1f;它是如何实现自增的&#xff1f;本文主要是深度解析 MySQL 默认存储引擎 InnoDB 与…

原点安全签约金网络数科,共建一体化数据安全防护体系

金网络正式携手原点安全&#xff0c;基于原点安全一体化数据安全平台&#xff08;uDSP&#xff09;&#xff0c;启动企业数据安全平台建设项目&#xff0c;围绕数据资产盘点、敏感数据识别与分类分级、数据访问权限管控、数据动态脱敏、数据安全审计与风险监测等关键能力建设&a…

mix-blend-mode的了解使用

mix-blend-mode 是 CSS 的一个属性&#xff0c;用于控制元素的内容&#xff08;如文本、图像、背景等&#xff09;如何与其 父元素 或 背景 进行混合。它类似于图形设计软件&#xff08;如 Photoshop&#xff09;中的图层混合模式&#xff0c;可以实现各种视觉效果&#xff1b;…

vue自定义指令bug

问题描述&#xff1a;页面加载时&#xff0c;报已下错误。同时&#xff0c;页面数据不显示环境介绍&#xff1a;已经添加了vue自定义指令permission&#xff0c;实现如下&#xff0c;用以控制元素显示权限app.directive(permission, (el, binding) > {if (!store.hasPermiss…

Vue3 + WebSocket

Vue3与WebSocket结合能够很好地满足实时通讯的需求。通过合理设计和管理WebSocket连接的生命周期&#xff0c;以及实现必要的重连逻辑和心跳检测机制&#xff0c;可以构建出响应迅速且稳定的实时应用。WebSocketWebSocket允许服务端主动向客户端发送数据&#xff0c;无需客户端…

IPSec和HTTPS对比(一)

IPSec&#xff08;Internet Protocol Security&#xff09;是网络层&#xff08;OSI第3层&#xff09;的加密协议&#xff0c;其核心机制和与HTTPS的区别如下&#xff1a;&#x1f512; ​一、IPSec的核心机制解析​​1. 安全封装结构​┌──────────┬───────…

关于 c、c#、c++ 三者区别

1. 起源与定位语言起源时间开发者定位/特点C1972年Dennis Ritchie面向过程的编程语言&#xff0c;强调底层控制与高效性能C1983年Bjarne Stroustrup在 C 的基础上加入 面向对象编程&#xff08;OOP&#xff09;C#2000年微软&#xff08;Microsoft&#xff09;类似 Java&#xf…

项目总体框架(servlet+axios+Mybatis)

项目总体框架 先暂时这样子&#xff08;后续发现错误的话就改&#xff09; com.hope-tieba/ ← 项目根 ├─ .idea/ ← IDEA 工程配置 ├─ src/ │ ├─ main/ │ │ ├─ java/ │ │ │ └─ com/hope/ │ │ …

RestTemplate 实现后端 HTTP 调用详解

1. 方法签名解析方法名和返回类型说明了这个方法的业务意图和数据结构。Override 表示实现接口方法&#xff0c;利于规范开发和自动检查。Override public List<RobotInfo> listRobots() {这里 RobotInfo 是假设的业务数据结构&#xff0c;实际项目中按你的类名即可。2. …

Python单例模式详解:从原理到实战的完整指南

引言 单例模式是软件设计中最常用的模式之一&#xff0c;它确保一个类只有一个实例&#xff0c;并提供全局访问点。在Python中&#xff0c;实现单例模式有多种优雅的方式&#xff0c;本文将详细讲解6种主流实现方法&#xff0c;包含完整代码示例和注释。 一、模块级单例&#x…

拼团系统中的幂等性防护 , 前置性查询,Redis 库存预判

这段内容涉及两个关键点&#xff1a;幂等性防护 和 拼团目标量判断&#xff0c;下面我将分别解释这两个问题&#xff0c;并重点说明&#xff1a; “如果没有拦截&#xff0c;最终访问数据&#xff0c;也会有数量判断拦截。” 这句话的意思。 ✅ 1. 查询外部交易 outTradeNo 是…

【Python】LEGB作用域 + re模块 + 正则表达式

文章目录一 LEGB作用域二 re&#xff08;Regular Expression&#xff09;预览1. re.match() —— 从字符串开头匹配2. re.search() —— 搜索整个字符串3. re.findall() —— 返回所有匹配的字符串列表4. re.finditer() —— 返回所有匹配的迭代器5. re.sub() —— 替换匹配的字…

JavaSE -- 数据操作流

6. 数据操作流在执行文件存储一个对象的时候&#xff0c;如果该对象只有少量属性需要存储&#xff0c;并且这些属性的类型都是基本数据类型&#xff0c;此时则不需要对象序列化技术。使用数据操作流既可以实现。 DataOutputStreamDataInputStream 注意&#xff1a; 读取数据的时…

GI6E 加密GRID電碼通信SHELLCODE載入

GI6E https://github.com/MartinxMax/gi6e 「它似乎能從特製的音訊信號中提取敏感資訊。」 HEX-GRID CODEX&#xff08;簡稱 HGC&#xff09;是一種自定義的 6 位元結構編碼系統&#xff0c;使用三位元的群組識別碼&#xff08;Group Bits&#xff09;加上三位元的索引識別碼…

实习十三——传输层协议

补充子网划分的主要目的就是为了节约IP&#xff0c;降低成本&#xff0c;但是如果划分私有IP网段&#xff0c;则完全没有意义&#xff0c;因为私有IP可重复&#xff0c;不要钱&#xff0c;所以私有IP严禁进行子网掩码划分传输层协议TCP三次握手TCP协议数据格式第一次握手&#…

RPG59.玩家拾取物品三:可拾取物品的提示UI

1。以WarriorWidgetBase作为父类&#xff0c;创建一个子类的userwidget2.布局为两个值都为1203。然后我们需要想办法&#xff0c;在合适的位置&#xff0c;用bool来控制此控件的显示与隐藏。情况为&#xff1a;当玩家触发与可拾取物体的重叠时&#xff0c;我们将广播一个bool值…

Vue.js 国际化 (i18n) 实践:让你的应用走向全球,多语言支持如此简单!

文章目录一、为何你的 Vue.js 应用需要“说多种语言”&#xff1f;国际化的重要性二、Vue I18n 基础实践&#xff1a;从零开始搭建多语言环境2.1 安装 Vue I18n2.2 配置 Vue I18n 实例2.3 在组件中使用翻译三、进阶实践&#xff1a;让国际化更强大、更灵活3.1 动态语言切换3.2 …