mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-29 12:06:51 +08:00
700 lines
16 KiB
Bash
Executable File
700 lines
16 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_URL="https://github.com/jxxghp/MoviePilot.git"
|
|
REPO_REF="v3"
|
|
WORKDIR="$PWD"
|
|
APP_DIR_NAME="MoviePilot"
|
|
LINK_CLI="true"
|
|
LINK_PATH=""
|
|
CONFIG_DIR=""
|
|
RUN_WIZARD="true"
|
|
START_AFTER_INSTALL="true"
|
|
NON_INTERACTIVE="false"
|
|
SUPERUSER=""
|
|
SUPERUSER_PASSWORD=""
|
|
OS_NAME="Unknown"
|
|
PYTHON_BIN=""
|
|
UV_VERSION="0.12.5"
|
|
BREW_BIN=""
|
|
PACKAGE_MANAGER=""
|
|
PACKAGE_INDEX_UPDATED="false"
|
|
PROMPT_INPUT="/dev/stdin"
|
|
PROMPT_OUTPUT="/dev/stdout"
|
|
HAS_TTY="false"
|
|
PATH_RC_FILE=""
|
|
PATH_UPDATED="false"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $(basename "$0") [OPTIONS]
|
|
|
|
Options:
|
|
--workdir PATH 克隆与安装的目标目录,默认当前目录
|
|
--app-dir NAME MoviePilot 目录名,默认 ${APP_DIR_NAME}
|
|
--repo-url URL 主项目仓库地址
|
|
--config-dir PATH 配置目录,默认使用程序目录外的系统配置目录
|
|
--superuser NAME 预设超级管理员用户名
|
|
--superuser-password PWD 预设超级管理员密码
|
|
--link-path PATH 全局 moviepilot 软链接位置
|
|
--no-link-cli 安装完成后不创建全局 moviepilot 命令
|
|
--no-wizard 跳过 moviepilot setup 的交互式初始化向导
|
|
--no-start 安装完成后不自动启动服务
|
|
--non-interactive 非交互模式,直接使用传入参数
|
|
-h, --help 显示帮助
|
|
|
|
Examples:
|
|
$(basename "$0")
|
|
$(basename "$0") --workdir ~/Projects
|
|
$(basename "$0") --config-dir ~/.config/moviepilot-local
|
|
$(basename "$0") --superuser admin --superuser-password 'ChangeMe123!'
|
|
$(basename "$0") --non-interactive --workdir ~/Projects --no-start
|
|
EOF
|
|
}
|
|
|
|
repo_dirty() {
|
|
(
|
|
cd "$1"
|
|
git status --porcelain --untracked-files=no 2>/dev/null | grep -q .
|
|
)
|
|
}
|
|
|
|
sync_repo() {
|
|
if [[ ! -d "$APP_DIR/.git" ]]; then
|
|
echo "==> 克隆 MoviePilot 到 $APP_DIR"
|
|
git clone --branch "$REPO_REF" "$REPO_URL" "$APP_DIR"
|
|
return
|
|
fi
|
|
|
|
echo "==> 复用已有 MoviePilot 仓库: $APP_DIR"
|
|
if repo_dirty "$APP_DIR"; then
|
|
echo "检测到现有仓库包含未提交改动,已停止自动更新。" >&2
|
|
echo "请先清理 $APP_DIR 的本地修改,或换一个新的安装目录后重试。" >&2
|
|
exit 1
|
|
fi
|
|
|
|
(
|
|
cd "$APP_DIR"
|
|
echo "==> 更新本地仓库到 origin/$REPO_REF"
|
|
git fetch --tags origin "$REPO_REF"
|
|
if git show-ref --verify --quiet "refs/heads/$REPO_REF"; then
|
|
git checkout "$REPO_REF"
|
|
else
|
|
git checkout -b "$REPO_REF" "origin/$REPO_REF"
|
|
fi
|
|
git pull --ff-only origin "$REPO_REF"
|
|
)
|
|
}
|
|
|
|
default_config_dir() {
|
|
case "$OS_NAME" in
|
|
macOS)
|
|
printf '%s\n' "$HOME/Library/Application Support/MoviePilot"
|
|
;;
|
|
*)
|
|
printf '%s\n' "${XDG_CONFIG_HOME:-$HOME/.config}/moviepilot"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
setup_prompt_io() {
|
|
if [[ -t 0 && -t 1 ]]; then
|
|
HAS_TTY="true"
|
|
return
|
|
fi
|
|
|
|
if [[ -r /dev/tty && -w /dev/tty ]]; then
|
|
PROMPT_INPUT="/dev/tty"
|
|
PROMPT_OUTPUT="/dev/tty"
|
|
HAS_TTY="true"
|
|
fi
|
|
}
|
|
|
|
detect_os() {
|
|
local uname_s
|
|
uname_s="$(uname -s)"
|
|
|
|
case "$uname_s" in
|
|
Darwin)
|
|
OS_NAME="macOS"
|
|
if command -v brew >/dev/null 2>&1; then
|
|
LINK_PATH="$(brew --prefix)/bin/moviepilot"
|
|
else
|
|
LINK_PATH="/usr/local/bin/moviepilot"
|
|
fi
|
|
;;
|
|
Linux)
|
|
if grep -qi microsoft /proc/version 2>/dev/null; then
|
|
OS_NAME="Linux (WSL)"
|
|
else
|
|
OS_NAME="Linux"
|
|
fi
|
|
LINK_PATH="/usr/local/bin/moviepilot"
|
|
;;
|
|
MINGW*|MSYS*|CYGWIN*)
|
|
OS_NAME="Windows"
|
|
;;
|
|
*)
|
|
OS_NAME="$uname_s"
|
|
LINK_PATH="/usr/local/bin/moviepilot"
|
|
;;
|
|
esac
|
|
|
|
if [[ -z "$CONFIG_DIR" ]]; then
|
|
CONFIG_DIR="$(default_config_dir)"
|
|
fi
|
|
}
|
|
|
|
detect_package_manager() {
|
|
case "$OS_NAME" in
|
|
macOS)
|
|
PACKAGE_MANAGER="brew"
|
|
;;
|
|
Linux*)
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="apt-get"
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="dnf"
|
|
elif command -v yum >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="yum"
|
|
elif command -v zypper >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="zypper"
|
|
elif command -v pacman >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="pacman"
|
|
elif command -v apk >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="apk"
|
|
else
|
|
PACKAGE_MANAGER=""
|
|
fi
|
|
;;
|
|
*)
|
|
PACKAGE_MANAGER=""
|
|
;;
|
|
esac
|
|
}
|
|
|
|
python_version_ok() {
|
|
local python_bin="$1"
|
|
"$python_bin" - <<'PY' >/dev/null 2>&1
|
|
import sys
|
|
raise SystemExit(0 if sys.version_info >= (3, 14) else 1)
|
|
PY
|
|
}
|
|
|
|
try_python_candidate() {
|
|
local candidate="$1"
|
|
local python_path=""
|
|
|
|
python_path="$(command -v "$candidate" 2>/dev/null || true)"
|
|
if [[ -n "$python_path" ]] && python_version_ok "$python_path"; then
|
|
printf '%s\n' "$python_path"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
find_python() {
|
|
local minor=""
|
|
for minor in 20 19 18 17 16 15 14 13 12; do
|
|
if try_python_candidate "python3.$minor"; then
|
|
return 0
|
|
fi
|
|
done
|
|
if try_python_candidate python3; then
|
|
return 0
|
|
fi
|
|
if try_python_candidate python; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
find_uv_python() {
|
|
local uv_bin="$1"
|
|
local minor=""
|
|
local python_path=""
|
|
|
|
for minor in 20 19 18 17 16 15 14 13 12 11; do
|
|
python_path="$("$uv_bin" python find "3.$minor" 2>/dev/null || true)"
|
|
if [[ -n "$python_path" ]] && python_version_ok "$python_path"; then
|
|
printf '%s\n' "$python_path"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
python_install_hint() {
|
|
case "$OS_NAME" in
|
|
macOS)
|
|
echo "脚本已尝试自动安装 Git、curl 和 Python 3.14+。" >&2
|
|
echo "如果自动安装失败,请先安装 Homebrew,或手动执行:brew install git curl python@3.14" >&2
|
|
;;
|
|
Linux*)
|
|
echo "脚本已尝试自动安装 Git、curl 和 Python 3.14+。" >&2
|
|
echo "如果自动安装失败,请先安装 Git、curl、Python 3.14+。" >&2
|
|
echo "例如 Debian/Ubuntu: sudo apt install git curl python3.14" >&2
|
|
echo "例如 Fedora/RHEL: sudo dnf install git curl python3.14" >&2
|
|
;;
|
|
Windows)
|
|
echo "推荐在 WSL、Linux 或 macOS 终端中运行此脚本。" >&2
|
|
;;
|
|
*)
|
|
echo "请先安装 Git、curl、Python 3.14+。" >&2
|
|
;;
|
|
esac
|
|
}
|
|
|
|
setup_brew_env() {
|
|
local candidate=""
|
|
for candidate in "$BREW_BIN" "$(command -v brew 2>/dev/null || true)" /opt/homebrew/bin/brew /usr/local/bin/brew /home/linuxbrew/.linuxbrew/bin/brew "$HOME/.linuxbrew/bin/brew"; do
|
|
if [[ -n "$candidate" && -x "$candidate" ]]; then
|
|
BREW_BIN="$candidate"
|
|
eval "$("$BREW_BIN" shellenv)"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
ensure_brew() {
|
|
if setup_brew_env; then
|
|
return 0
|
|
fi
|
|
|
|
echo "==> 未找到 Homebrew,开始自动安装"
|
|
NONINTERACTIVE=1 CI=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
if ! setup_brew_env; then
|
|
echo "自动安装 Homebrew 失败。" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
run_privileged() {
|
|
if [[ "$(id -u)" -eq 0 ]]; then
|
|
"$@"
|
|
return
|
|
fi
|
|
|
|
if ! command -v sudo >/dev/null 2>&1; then
|
|
echo "当前步骤需要 sudo 权限,但系统中未找到 sudo。" >&2
|
|
return 1
|
|
fi
|
|
|
|
if [[ "$HAS_TTY" == "true" ]]; then
|
|
sudo "$@"
|
|
return
|
|
fi
|
|
|
|
if sudo -n true >/dev/null 2>&1; then
|
|
sudo -n "$@"
|
|
return
|
|
fi
|
|
|
|
echo "当前步骤需要 sudo 权限,请在可交互终端中重新运行脚本。" >&2
|
|
return 1
|
|
}
|
|
|
|
refresh_package_index() {
|
|
if [[ "$PACKAGE_INDEX_UPDATED" == "true" ]]; then
|
|
return
|
|
fi
|
|
|
|
case "$PACKAGE_MANAGER" in
|
|
apt-get)
|
|
run_privileged apt-get update
|
|
;;
|
|
pacman)
|
|
run_privileged pacman -Sy --noconfirm
|
|
;;
|
|
zypper)
|
|
run_privileged zypper --gpg-auto-import-keys refresh
|
|
;;
|
|
apk)
|
|
run_privileged apk update
|
|
;;
|
|
esac
|
|
|
|
PACKAGE_INDEX_UPDATED="true"
|
|
}
|
|
|
|
install_system_packages() {
|
|
local packages=("$@")
|
|
if [[ "${#packages[@]}" -eq 0 ]]; then
|
|
return 0
|
|
fi
|
|
|
|
case "$PACKAGE_MANAGER" in
|
|
brew)
|
|
ensure_brew
|
|
"$BREW_BIN" install "${packages[@]}"
|
|
;;
|
|
apt-get)
|
|
refresh_package_index
|
|
run_privileged apt-get install -y "${packages[@]}"
|
|
;;
|
|
dnf)
|
|
run_privileged dnf install -y "${packages[@]}"
|
|
;;
|
|
yum)
|
|
run_privileged yum install -y "${packages[@]}"
|
|
;;
|
|
zypper)
|
|
refresh_package_index
|
|
run_privileged zypper install -y "${packages[@]}"
|
|
;;
|
|
pacman)
|
|
refresh_package_index
|
|
run_privileged pacman -S --noconfirm --needed "${packages[@]}"
|
|
;;
|
|
apk)
|
|
refresh_package_index
|
|
run_privileged apk add --no-cache "${packages[@]}"
|
|
;;
|
|
*)
|
|
echo "当前系统暂不支持自动安装依赖,请手动安装:${packages[*]}" >&2
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
ensure_base_tools() {
|
|
local missing=()
|
|
|
|
if ! command -v git >/dev/null 2>&1; then
|
|
missing+=("git")
|
|
fi
|
|
|
|
if ! command -v curl >/dev/null 2>&1; then
|
|
missing+=("curl")
|
|
fi
|
|
|
|
if [[ "${#missing[@]}" -eq 0 ]]; then
|
|
return 0
|
|
fi
|
|
|
|
echo "==> 自动安装基础依赖: ${missing[*]}"
|
|
install_system_packages "${missing[@]}"
|
|
hash -r
|
|
|
|
if ! command -v git >/dev/null 2>&1 || ! command -v curl >/dev/null 2>&1; then
|
|
echo "基础依赖安装失败,请确认 git 和 curl 可用后重试。" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
ensure_uv() {
|
|
if command -v uv >/dev/null 2>&1 \
|
|
&& [[ "$(uv --version 2>/dev/null | awk '{print $2}')" == "${UV_VERSION}" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
echo "==> 自动安装 uv ${UV_VERSION}"
|
|
env UV_INSTALL_DIR="$HOME/.local/bin" sh -c "$(curl -LsSf "https://astral.sh/uv/${UV_VERSION}/install.sh")"
|
|
export PATH="$HOME/.local/bin:$PATH"
|
|
hash -r
|
|
|
|
if ! command -v uv >/dev/null 2>&1 \
|
|
|| [[ "$(uv --version 2>/dev/null | awk '{print $2}')" != "${UV_VERSION}" ]]; then
|
|
echo "uv ${UV_VERSION} 安装失败,无法继续自动安装 Python。" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
ensure_python() {
|
|
PYTHON_BIN="$(find_python || true)"
|
|
if [[ -n "$PYTHON_BIN" ]] && python_version_ok "$PYTHON_BIN"; then
|
|
return 0
|
|
fi
|
|
|
|
ensure_uv
|
|
|
|
PYTHON_BIN="$(find_uv_python "$(command -v uv)" || true)"
|
|
if [[ -n "$PYTHON_BIN" ]] && python_version_ok "$PYTHON_BIN"; then
|
|
return 0
|
|
fi
|
|
|
|
echo "==> 未找到可用的 Python 3.14+,开始自动安装 Python 3.14"
|
|
uv python install 3.14
|
|
PYTHON_BIN="$(find_uv_python "$(command -v uv)" || true)"
|
|
if [[ -z "$PYTHON_BIN" ]] || ! python_version_ok "$PYTHON_BIN"; then
|
|
echo "自动安装 Python 3.14 失败。" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
ensure_prereqs() {
|
|
if [[ "$OS_NAME" == "Windows" ]]; then
|
|
echo "检测到当前环境为 Windows shell,建议改用 WSL、Linux 或 macOS 终端运行。" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! ensure_base_tools || ! ensure_python || ! ensure_uv; then
|
|
python_install_hint
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
prompt_text() {
|
|
local label="$1"
|
|
local default_value="${2:-}"
|
|
local answer=""
|
|
|
|
if [[ -n "$default_value" ]]; then
|
|
printf '%s [%s]: ' "$label" "$default_value" >"$PROMPT_OUTPUT"
|
|
else
|
|
printf '%s: ' "$label" >"$PROMPT_OUTPUT"
|
|
fi
|
|
|
|
IFS= read -r answer <"$PROMPT_INPUT" || true
|
|
if [[ -z "$answer" ]]; then
|
|
answer="$default_value"
|
|
fi
|
|
printf '%s\n' "$answer"
|
|
}
|
|
|
|
prompt_yes_no() {
|
|
local label="$1"
|
|
local default_value="${2:-y}"
|
|
local answer=""
|
|
local prompt="[y/N]"
|
|
|
|
if [[ "$default_value" == "y" ]]; then
|
|
prompt="[Y/n]"
|
|
fi
|
|
|
|
while true; do
|
|
printf '%s %s: ' "$label" "$prompt" >"$PROMPT_OUTPUT"
|
|
IFS= read -r answer <"$PROMPT_INPUT" || true
|
|
answer="$(printf '%s' "$answer" | tr '[:upper:]' '[:lower:]')"
|
|
if [[ -z "$answer" ]]; then
|
|
answer="$default_value"
|
|
fi
|
|
case "$answer" in
|
|
y|yes) return 0 ;;
|
|
n|no) return 1 ;;
|
|
esac
|
|
printf '请输入 y 或 n。\n' >"$PROMPT_OUTPUT"
|
|
done
|
|
}
|
|
|
|
run_interactive_guide() {
|
|
printf '==> 当前系统: %s\n' "$OS_NAME" >"$PROMPT_OUTPUT"
|
|
printf '==> 将自动拉取 MoviePilot,并下载前端 release、资源文件与本地 Node 运行时\n' >"$PROMPT_OUTPUT"
|
|
|
|
WORKDIR="$(prompt_text "安装目录" "$WORKDIR")"
|
|
APP_DIR_NAME="$(prompt_text "主项目目录名" "$APP_DIR_NAME")"
|
|
CONFIG_DIR="$(prompt_text "配置目录" "$CONFIG_DIR")"
|
|
|
|
if prompt_yes_no "安装过程中进入 MoviePilot 初始化向导" "y"; then
|
|
RUN_WIZARD="true"
|
|
else
|
|
RUN_WIZARD="false"
|
|
fi
|
|
|
|
if prompt_yes_no "安装完成后立即启动前后端服务" "y"; then
|
|
START_AFTER_INSTALL="true"
|
|
else
|
|
START_AFTER_INSTALL="false"
|
|
fi
|
|
}
|
|
|
|
ensure_link_path() {
|
|
if [[ "$LINK_CLI" != "true" ]]; then
|
|
return
|
|
fi
|
|
|
|
if [[ -z "$LINK_PATH" ]]; then
|
|
LINK_PATH="/usr/local/bin/moviepilot"
|
|
fi
|
|
|
|
local link_dir
|
|
link_dir="$(dirname "$LINK_PATH")"
|
|
if mkdir -p "$link_dir" 2>/dev/null && [[ -w "$link_dir" ]]; then
|
|
return
|
|
fi
|
|
|
|
LINK_PATH="$HOME/.local/bin/moviepilot"
|
|
mkdir -p "$(dirname "$LINK_PATH")"
|
|
}
|
|
|
|
detect_rc_file() {
|
|
local shell_name
|
|
shell_name="$(basename "${SHELL:-}")"
|
|
case "$shell_name" in
|
|
zsh)
|
|
printf '%s\n' "$HOME/.zshrc"
|
|
;;
|
|
bash)
|
|
printf '%s\n' "$HOME/.bashrc"
|
|
;;
|
|
*)
|
|
printf '%s\n' "$HOME/.profile"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
ensure_path_configured() {
|
|
if [[ "$LINK_CLI" != "true" ]]; then
|
|
return
|
|
fi
|
|
|
|
local bin_dir
|
|
bin_dir="$(dirname "$LINK_PATH")"
|
|
export PATH="$bin_dir:$PATH"
|
|
|
|
if [[ "$bin_dir" != "$HOME/.local/bin" ]]; then
|
|
return
|
|
fi
|
|
|
|
PATH_RC_FILE="$(detect_rc_file)"
|
|
local export_line='export PATH="$HOME/.local/bin:$PATH"'
|
|
mkdir -p "$(dirname "$PATH_RC_FILE")"
|
|
touch "$PATH_RC_FILE"
|
|
|
|
if ! grep -Fqs "$export_line" "$PATH_RC_FILE"; then
|
|
{
|
|
printf '\n# MoviePilot CLI\n'
|
|
printf '%s\n' "$export_line"
|
|
} >>"$PATH_RC_FILE"
|
|
PATH_UPDATED="true"
|
|
fi
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--workdir)
|
|
WORKDIR="$2"
|
|
shift 2
|
|
;;
|
|
--app-dir)
|
|
APP_DIR_NAME="$2"
|
|
shift 2
|
|
;;
|
|
--repo-url)
|
|
REPO_URL="$2"
|
|
shift 2
|
|
;;
|
|
--config-dir)
|
|
CONFIG_DIR="$2"
|
|
shift 2
|
|
;;
|
|
--superuser)
|
|
SUPERUSER="$2"
|
|
shift 2
|
|
;;
|
|
--superuser-password)
|
|
SUPERUSER_PASSWORD="$2"
|
|
shift 2
|
|
;;
|
|
--link-path)
|
|
LINK_PATH="$2"
|
|
shift 2
|
|
;;
|
|
--no-link-cli)
|
|
LINK_CLI="false"
|
|
shift
|
|
;;
|
|
--no-wizard)
|
|
RUN_WIZARD="false"
|
|
shift
|
|
;;
|
|
--no-start)
|
|
START_AFTER_INSTALL="false"
|
|
shift
|
|
;;
|
|
--non-interactive)
|
|
NON_INTERACTIVE="true"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "未知参数: $1" >&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
detect_os
|
|
detect_package_manager
|
|
setup_prompt_io
|
|
ensure_prereqs
|
|
ensure_link_path
|
|
|
|
if [[ "$NON_INTERACTIVE" != "true" && "$HAS_TTY" == "true" ]]; then
|
|
run_interactive_guide
|
|
ensure_link_path
|
|
elif [[ "$RUN_WIZARD" == "true" && "$HAS_TTY" != "true" ]]; then
|
|
echo "==> 未检测到可用终端输入,已跳过初始化向导。安装完成后可手动执行:moviepilot setup --wizard"
|
|
RUN_WIZARD="false"
|
|
fi
|
|
|
|
mkdir -p "$WORKDIR"
|
|
WORKDIR="$(cd "$WORKDIR" && pwd)"
|
|
APP_DIR="$WORKDIR/$APP_DIR_NAME"
|
|
sync_repo
|
|
|
|
cd "$APP_DIR"
|
|
echo "==> 执行本地环境安装与初始化"
|
|
SETUP_ARGS=(setup --python "$PYTHON_BIN" --config-dir "$CONFIG_DIR")
|
|
if [[ "$RUN_WIZARD" == "true" ]]; then
|
|
SETUP_ARGS+=(--wizard)
|
|
fi
|
|
if [[ -n "$SUPERUSER" ]]; then
|
|
SETUP_ARGS+=(--superuser "$SUPERUSER")
|
|
fi
|
|
if [[ -n "$SUPERUSER_PASSWORD" ]]; then
|
|
SETUP_ARGS+=(--superuser-password "$SUPERUSER_PASSWORD")
|
|
fi
|
|
if [[ "$HAS_TTY" == "true" ]]; then
|
|
"$PYTHON_BIN" ./scripts/local_setup.py "${SETUP_ARGS[@]}" <"$PROMPT_INPUT"
|
|
else
|
|
"$PYTHON_BIN" ./scripts/local_setup.py "${SETUP_ARGS[@]}"
|
|
fi
|
|
|
|
if [[ "$LINK_CLI" == "true" ]]; then
|
|
echo "==> 创建全局 moviepilot 命令到 $LINK_PATH"
|
|
ln -sf "$APP_DIR/moviepilot" "$LINK_PATH"
|
|
ensure_path_configured
|
|
fi
|
|
|
|
if [[ "$START_AFTER_INSTALL" == "true" ]]; then
|
|
echo "==> 启动 MoviePilot 前后端服务"
|
|
./moviepilot start
|
|
fi
|
|
|
|
cat <<EOF
|
|
==> 安装完成
|
|
|
|
系统环境: $OS_NAME
|
|
项目目录: $APP_DIR
|
|
配置目录: $CONFIG_DIR
|
|
Python 解释器: $PYTHON_BIN
|
|
CLI 命令: ${LINK_CLI:-false}
|
|
CLI 路径: ${LINK_PATH:-未创建}
|
|
|
|
使用方式:
|
|
moviepilot status
|
|
moviepilot logs --frontend
|
|
moviepilot logs --stdio
|
|
moviepilot config path
|
|
|
|
完整 CLI 文档:
|
|
$APP_DIR/docs/cli.md
|
|
EOF
|
|
|
|
if [[ "$LINK_CLI" == "true" && "$(dirname "$LINK_PATH")" == "$HOME/.local/bin" ]]; then
|
|
echo
|
|
echo "PATH 说明:"
|
|
if [[ "$PATH_UPDATED" == "true" ]]; then
|
|
echo " 已将 ~/.local/bin 写入 $PATH_RC_FILE"
|
|
fi
|
|
echo " 如果当前终端仍提示找不到 moviepilot,请重新打开终端,或执行:"
|
|
echo " source ${PATH_RC_FILE:-$HOME/.profile}"
|
|
fi
|