183 lines
5.0 KiB
Bash
183 lines
5.0 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# openlist 一键安装脚本
|
||
# 用法示例:curl -fsSL "https://pan.shumengya.top/d/scripts/openlist/install_openlist.sh" | bash
|
||
|
||
BASE_URL="https://pan.shumengya.top/d/scripts/openlist/openlist"
|
||
INSTALL_DIR="/shumengya/bin/openlist"
|
||
SERVICE_NAME="smy-openlist"
|
||
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||
|
||
log() { printf '[openlist-安装] %s\n' "$*" >&2; }
|
||
fail() { log "错误: $*" >&2; exit 1; }
|
||
|
||
# 进度条函数
|
||
show_progress() {
|
||
local pid=$1
|
||
local text=$2
|
||
local delay=0.1
|
||
local spin='-\|/'
|
||
|
||
printf "[openlist-安装] %s... " "$text" >&2
|
||
|
||
while ps -p "$pid" > /dev/null 2>&1; do
|
||
local temp=${spin#?}
|
||
printf "\b%c" "$spin" >&2
|
||
local spin=$temp${spin%"$temp"}
|
||
sleep $delay
|
||
done
|
||
printf "\b完成\n" >&2
|
||
}
|
||
|
||
check_port() {
|
||
# 检查端口占用并尝试清理
|
||
local port=5244
|
||
if lsof -i :$port >/dev/null 2>&1 || netstat -tunlp | grep -q ":$port "; then
|
||
log "检测到端口 $port 被占用,尝试清理..."
|
||
fuser -k -n tcp $port >/dev/null 2>&1 || true
|
||
sleep 1
|
||
if lsof -i :$port >/dev/null 2>&1; then
|
||
# 尝试查找占用进程并强制杀掉
|
||
local pid
|
||
pid=$(lsof -t -i:$port 2>/dev/null || true)
|
||
if [ -n "$pid" ]; then
|
||
kill -9 "$pid" 2>/dev/null || true
|
||
fi
|
||
fi
|
||
fi
|
||
}
|
||
|
||
require_root() {
|
||
# 必须使用 root 权限执行
|
||
if [ "${EUID:-$(id -u)}" -ne 0 ]; then
|
||
fail "请使用 root 权限运行 (sudo bash install_openlist.sh)"
|
||
fi
|
||
}
|
||
|
||
detect_arch() {
|
||
# 自动检测 CPU 架构,选择对应二进制
|
||
local machine
|
||
machine=$(uname -m)
|
||
case "$machine" in
|
||
x86_64|amd64) echo "amd64" ;;
|
||
aarch64|arm64) echo "arm64" ;;
|
||
*) fail "不支持的架构: $machine" ;;
|
||
esac
|
||
}
|
||
|
||
download_files() {
|
||
# 下载对应架构的二进制包和 data 目录
|
||
local arch tmp_dir binary_url data_url
|
||
arch="$1"
|
||
tmp_dir=$(mktemp -d)
|
||
# 只在 tmp_dir 存在时清理
|
||
trap 'if [ -n "${tmp_dir:-}" ] && [ -d "$tmp_dir" ]; then rm -rf "$tmp_dir"; fi' EXIT
|
||
|
||
binary_url="${BASE_URL}/linux-${arch}.tar.gz"
|
||
data_url="${BASE_URL}/data.tgz"
|
||
|
||
# 后台下载并显示进度
|
||
curl -fsSL "$binary_url" -o "$tmp_dir/openlist.tar.gz" &
|
||
show_progress $! "正在下载 ${arch} 架构的二进制文件"
|
||
[ -f "$tmp_dir/openlist.tar.gz" ] || fail "下载二进制文件失败"
|
||
|
||
# 检查 data 目录是否已存在,如果存在则跳过下载
|
||
if [ -d "$INSTALL_DIR/data" ]; then
|
||
log "检测到已存在 data 目录,跳过下载以保护现有数据"
|
||
else
|
||
curl -fsSL "$data_url" -o "$tmp_dir/data.tgz" &
|
||
show_progress $! "正在下载 data 配置文件"
|
||
[ -f "$tmp_dir/data.tgz" ] || fail "下载 data 文件失败"
|
||
fi
|
||
|
||
echo "$tmp_dir"
|
||
}
|
||
|
||
install_binary_and_data() {
|
||
# 解压并安装二进制文件和 data 目录
|
||
local tmp_dir extracted_dir bin_path
|
||
tmp_dir="$1"
|
||
|
||
log "正在安装 openlist 到 $INSTALL_DIR..."
|
||
|
||
# 尝试停止服务
|
||
systemctl stop "$SERVICE_NAME" 2>/dev/null || true
|
||
# 检查并清理端口
|
||
check_port
|
||
|
||
mkdir -p "$INSTALL_DIR"
|
||
|
||
# 只在下载了 data.tgz 时才解压
|
||
if [ -f "$tmp_dir/data.tgz" ]; then
|
||
tar -xzf "$tmp_dir/data.tgz" -C "$INSTALL_DIR/" || fail "解压 data 目录失败"
|
||
else
|
||
log "保留现有 data 目录,不进行覆盖"
|
||
fi
|
||
|
||
# 解压二进制文件
|
||
extracted_dir=$(mktemp -d)
|
||
trap 'if [ -n "${tmp_dir:-}" ] && [ -d "$tmp_dir" ]; then rm -rf "$tmp_dir"; fi; if [ -n "${extracted_dir:-}" ] && [ -d "$extracted_dir" ]; then rm -rf "$extracted_dir"; fi' EXIT
|
||
tar -xzf "$tmp_dir/openlist.tar.gz" -C "$extracted_dir" || fail "解压二进制文件失败"
|
||
bin_path=$(find "$extracted_dir" -maxdepth 2 -type f -name "openlist" -perm -111 | head -n 1)
|
||
[ -n "$bin_path" ] || fail "未找到 openlist 可执行文件"
|
||
cp "$bin_path" "$INSTALL_DIR/openlist" || fail "复制可执行文件失败"
|
||
chmod +x "$INSTALL_DIR/openlist"
|
||
log "文件安装完成"
|
||
}
|
||
|
||
write_service() {
|
||
# 写入 systemd 服务文件,默认自启动并在失败时重启
|
||
log "正在配置 systemd 服务..."
|
||
cat > "$SERVICE_FILE" <<'EOF'
|
||
[Unit]
|
||
Description=openlist
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=root
|
||
Group=root
|
||
WorkingDirectory=/shumengya/bin/openlist
|
||
ExecStart=/shumengya/bin/openlist/openlist server
|
||
Restart=on-failure
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
}
|
||
|
||
enable_service() {
|
||
# 重新加载 systemd,设置开机自启并立即启动
|
||
log "正在启用并启动服务..."
|
||
systemctl daemon-reload
|
||
systemctl enable "$SERVICE_NAME"
|
||
systemctl restart "$SERVICE_NAME"
|
||
|
||
# 等待几秒钟以捕获立即崩溃的情况
|
||
sleep 3
|
||
}
|
||
|
||
main() {
|
||
require_root
|
||
local arch tmp_dir=""
|
||
arch=$(detect_arch)
|
||
log "检测到系统架构: $arch"
|
||
tmp_dir=$(download_files "$arch")
|
||
install_binary_and_data "$tmp_dir"
|
||
write_service
|
||
enable_service
|
||
log "=========================================="
|
||
log "安装完成! openlist 已安装到: $INSTALL_DIR"
|
||
log "服务已启动,查看状态: systemctl status $SERVICE_NAME"
|
||
|
||
# 检查服务状态
|
||
if ! systemctl is-active --quiet "$SERVICE_NAME"; then
|
||
log "警告: 服务未能正常启动"
|
||
journalctl -u "$SERVICE_NAME" --no-pager -n 20
|
||
fi
|
||
log "=========================================="
|
||
}
|
||
|
||
main "$@"
|