1.问题
erp项目,每个商户一个站点,每个站点都需要配置4个supervisor进程,非常麻烦,而且很容易出错,故使用.ini配置文件方式来控制进程
2.执行脚本
#!/bin/bash
# 获取脚本的绝对路径
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 定义 .env 文件路径(上上层目录:父目录的父目录)
PARENT_DIR=$(dirname "$SCRIPT_DIR")
GRANDPARENT_DIR=$(dirname "$PARENT_DIR")
ENV_PATH="$GRANDPARENT_DIR/.env"
# 检查 .env 文件是否存在
if [ ! -f "$ENV_PATH" ]; then
echo "错误: 找不到 .env 文件"
exit 1
fi
# 安全地读取 .env 文件
while IFS= read -r line || [[ -n "$line" ]]; do
# 跳过空行和注释
if [[ -z "$line" ]] || [[ "$line" =~ ^[[:space:]]*# ]]; then
continue
fi
# 移除 export 关键字和空格
line_clean=$(echo "$line" | sed 's/^export[[:space:]]*//')
# 提取键值对
key=$(echo "$line_clean" | cut -d '=' -f1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
value=$(echo "$line_clean" | cut -d '=' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
# 去除可能的引号
value=$(echo "$value" | sed -e "s/^['\"]//;s/['\"]$//")
# 根据键设置变量(注意:.env 中是大写的 PATH 和 NUM)
case "$key" in
PATH)
path="$value"
;;
NUM)
num="$value"
;;
esac
done < "$ENV_PATH"
# 检查必需的变量
if [ -z "${path}" ]; then
echo "错误: .env 文件中缺少 'PATH' 配置"
exit 1
fi
if [ -z "${num}" ]; then
echo "错误: .env 文件中缺少 'NUM' 配置"
exit 1
fi
# 构建文件路径
expire="$path/public/supervisor/expire.ini"
expire_notice="$path/public/supervisor/expire_notice.ini"
free_call_num="$path/public/supervisor/free_call_num.ini"
socket="$path/public/supervisor/socket.ini"
# supervisor 配置路径
supervisor_path="/www/server/panel/plugin/supervisor/profile"
supervisor_expire="$supervisor_path/hsl_expire_$num.ini"
supervisor_expire_notice="$supervisor_path/hsl_expire_notice_$num.ini"
supervisor_free_call_num="$supervisor_path/hsl_free_call_num_$num.ini"
supervisor_socket="$supervisor_path/hsl_socket_$num.ini"
# 创建一个函数来处理文件复制和替换逻辑
process_file() {
local source_file="$1"
local target_file="$2"
if [ -e "$source_file" ]; then
# 读取文件内容
content=$(cat "$source_file")
# 替换 %path% 和 %num%(注意模板中的占位符是小写)
# 将模板中的小写占位符替换为实际值
replaced_content=$(echo "$content" | sed "s|%path%|$path|g; s|%num%|$num|g")
# 检查目标文件是否存在
if [ ! -e "$target_file" ]; then
echo "$replaced_content" > "$target_file"
$(/www/server/panel/pyenv/bin/supervisorctl update)
else
# 目标文件存在,比较内容
if ! echo "$replaced_content" | diff -q "$target_file" - > /dev/null 2>&1; then
echo "更新文件: $target_file"
echo "$replaced_content" > "$target_file"
$(/www/server/panel/pyenv/bin/supervisorctl update)
else
echo "文件内容相同,无需更新: $target_file"
fi
fi
else
echo "警告: 源文件不存在: $source_file"
fi
}
# 处理每个文件
process_file "$expire" "$supervisor_expire"
process_file "$expire_notice" "$supervisor_expire_notice"
process_file "$free_call_num" "$supervisor_free_call_num"
process_file "$socket" "$supervisor_socket" "socket_"
echo "处理完成!"
3. 配置文件–.ini
[program:hsl_expire_%num%] command=php think queue:listen --queue=expire_%num% directory=%path% autorestart=true startsecs=3 startretries=3 stdout_logfile=/www/server/panel/plugin/supervisor/log/expire_%num%.out.log stderr_logfile=/www/server/panel/plugin/supervisor/log/expire_%num%.err.log stdout_logfile_maxbytes=2MB stderr_logfile_maxbytes=2MB user=www priority=999 numprocs=1 process_name=%(program_name)s_%(process_num)02d
4.注意
1.program的hsl的前缀目的是服务器异常的时候同时查出来这个进程,方便杀死 2.宝塔里面的supervisor要求文件名和进程名必须完全一致,所以会有修改文件这一步--文件名和.ini里面的program名称保持一致 3.源文件是是public/supervisor的文件,写入到宝塔的supervisor配置文件 4. 原理:手写supervisor的配置文件,并且读取成功之后放到宝塔的supervisor配置目录下,然后重启supervisor服务
