三个脚本的实现启动、停止、重启一个可执行程序,并记录其PID
示例目录结构
markdown
dir/
├── app.linux # 可执行文件
├── conf/
│ ├── config.yml
├── start.sh
├── stop.sh
├── restart.sh
├── app.log # 运行脚本自动生成 程序运行时输入日志的记录到这里
└── app.pid # 运行脚本自动生成 进程pid1. start.sh
bash
#!/bin/bash
# 获取脚本所在目录的绝对路径
__DIRNAME=$(dirname "$(readlink -f "$0")")
APP_NAME="app名称"
START_COMMAND="${__DIRNAME}/app.linux" # 仅包含命令路径
ARGS="run ${__DIRNAME}/conf/config.yml" # 参数单独保存
PID_FILE="${__DIRNAME}/app.pid"
LOG_FILE="${__DIRNAME}/app.log"
# 检查是否已经运行
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if kill -0 "$PID" >/dev/null 2>&1; then
echo "程序 $APP_NAME 已经在运行 (PID: $PID)"
exit 1
else
echo "发现陈旧的 PID 文件,清理后启动..."
rm -f "$PID_FILE"
fi
fi
# 启动程序并记录 PID 输入日志到LOG_FILE
nohup $START_COMMAND $ARGS > "$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
echo "程序 $APP_NAME 已启动 (PID: $!)"2. stop.sh
- 停止时检查现在pid实际运行命令是否包含
start.sh中的启动命令
bash
#!/bin/bash
# 获取脚本所在目录的绝对路径
__DIRNAME=$(dirname "$(readlink -f "$0")")
APP_NAME="app名称"
PID_FILE="${__DIRNAME}/app.pid"
# 关键:匹配进程实际运行的预期包含命令(示例中匹配 "app.linux" 关键字)
EXPECTED_CMD="app.linux"
# 检查 PID 文件是否存在
if [ ! -f "$PID_FILE" ]; then
echo "错误:PID 文件不存在,程序可能未运行"
exit 1
fi
# 读取 PID 并检查有效性
PID=$(cat "$PID_FILE")
if [ -z "$PID" ]; then
echo "错误:PID 文件内容为空,清理并退出"
rm -f "$PID_FILE"
exit 1
fi
# 检查 PID 是否存在
if ! kill -0 "$PID" >/dev/null 2>&1; then
echo "警告:进程 $PID 不存在,清理 PID 文件"
rm -f "$PID_FILE"
exit 1
fi
# 关键验证:检查 PID 对应的进程是否是目标程序
PROCESS_CMD=$(ps -p "$PID" -o cmd=) # 获取进程完整命令行
if [[ "$PROCESS_CMD" != *"$EXPECTED_CMD"* ]]; then
echo "错误:PID $PID 不属于 $APP_NAME,进程命令不包含:$EXPECTED_CMD,实际进程命令为:$PROCESS_CMD"
exit 1
fi
# 执行终止操作
kill "$PID"
echo "程序 $APP_NAME (PID: $PID) 已终止"
rm -f "$PID_FILE"3. restart.sh
bash
#!/bin/bash
# 获取脚本所在目录的绝对路径
__DIRNAME=$(dirname "$(readlink -f "$0")")
"${__DIRNAME}/stop.sh"
sleep 1 # 可选:等待进程完全停止
"${__DIRNAME}/start.sh"使用方法:
- 将上述脚本保存为
start.sh,stop.sh,restart.sh - 替换
APP_NAME="myapp"为你的可执行程序名称 - 赋予执行权限:bash
chmod +x start.sh stop.sh restart.sh - 启动程序:bash
./start.sh - 停止程序:bash
./stop.sh - 重启程序:bash
./restart.sh
关键点说明:
- PID 文件:脚本通过
app.pid文件记录进程ID - 日志记录:程序输出会重定向到
app.log - 防重复启动:
start.sh会检查现有进程是否运行 - 陈旧 PID 处理:
stop.sh会自动清理无效的 PID 文件 - 权限要求:确保脚本和程序有可执行权限
- unix换行符:确保脚本文件使用 Unix 换行符(LF),避免 Windows 换行符(CRLF)的问题
可以根据实际需求调整日志路径、等待时间等参数。