diff --git a/deploy/README.md b/deploy/README.md index c48e12c..0fe9a4f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -31,6 +31,20 @@ cd C:\path\to\crypto_monitor ## Linux / macOS +**Ubuntu / Debian 首次部署**(若 `python -m venv` 报 `ensurepip is not available`): + +```bash +apt update +apt install -y python3.10-venv python3-pip curl # 版本号与 python3 --version 一致 +bash deploy/setup_env.sh +``` + +脚本在 **root** 下会自动尝试 `apt install python*-venv`;非 root 请先装系统包或使用: + +```bash +sudo bash deploy/setup_env.sh --install-system-deps +``` + ```bash cd /opt/crypto_monitor bash deploy/setup_env.sh diff --git a/deploy/setup_env.sh b/deploy/setup_env.sh index 79ba17d..bf64c19 100644 --- a/deploy/setup_env.sh +++ b/deploy/setup_env.sh @@ -6,6 +6,7 @@ # bash deploy/setup_env.sh --only binance,gate_bot # bash deploy/setup_env.sh --skip-pm2 # bash deploy/setup_env.sh --recreate-venv +# bash deploy/setup_env.sh --install-system-deps # root + apt 时安装 python*-venv # set -e set -u @@ -23,6 +24,8 @@ ONLY="all" SKIP_PM2=0 SKIP_ENV_COPY=0 RECREATE_VENV=0 +INSTALL_APT_DEPS=0 +PY="" usage() { sed -n '2,12p' "$0" | sed 's/^# \?//' @@ -35,6 +38,7 @@ while [[ $# -gt 0 ]]; do --skip-pm2) SKIP_PM2=1; shift ;; --skip-env-copy) SKIP_ENV_COPY=1; shift ;; --recreate-venv) RECREATE_VENV=1; shift ;; + --install-system-deps) INSTALL_APT_DEPS=1; shift ;; -h|--help) usage 0 ;; *) echo "未知参数: $1" >&2; usage 1 ;; esac @@ -83,6 +87,86 @@ check_python_version() { echo "Python: $("${py}" --version 2>&1)" } +python_minor_version() { + local py="$1" + "${py}" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' +} + +check_venv_available() { + local py="$1" + local tmp + tmp="$(mktemp -d 2>/dev/null || mktemp -d -t cmvenv)" + if "${py}" -m venv "${tmp}" >/dev/null 2>&1 && [[ -x "${tmp}/bin/python" ]]; then + rm -rf "${tmp}" + return 0 + fi + rm -rf "${tmp}" 2>/dev/null || true + return 1 +} + +install_debian_venv_packages() { + local py="$1" + local ver + ver="$(python_minor_version "${py}")" + if ! command -v apt-get >/dev/null 2>&1; then + echo " 未检测到 apt-get,请手动安装 python${ver}-venv 与 python3-pip" >&2 + return 1 + fi + if [[ "$(id -u)" -ne 0 ]]; then + echo " 需要 root 安装系统包,请执行:" >&2 + echo " sudo apt update && sudo apt install -y python${ver}-venv python3-pip curl" >&2 + echo " 或: sudo bash deploy/setup_env.sh --install-system-deps" >&2 + return 1 + fi + step "安装系统依赖 (python${ver}-venv) ..." + export DEBIAN_FRONTEND=noninteractive + apt-get update -qq + if ! apt-get install -y "python${ver}-venv" python3-pip curl ca-certificates; then + apt-get install -y python3-venv python3-pip curl ca-certificates + fi +} + +ensure_venv_prereqs() { + local py="$1" + if check_venv_available "${py}"; then + return 0 + fi + echo " 当前 Python 无法创建 venv(缺少 ensurepip,常见于未安装 python*-venv)" >&2 + if [[ "${INSTALL_APT_DEPS}" -eq 1 ]] || [[ "$(id -u)" -eq 0 ]]; then + install_debian_venv_packages "${py}" || exit 1 + if check_venv_available "${py}"; then + return 0 + fi + fi + local ver + ver="$(python_minor_version "${py}")" + echo "请安装后重试:" >&2 + echo " apt update && apt install -y python${ver}-venv python3-pip" >&2 + echo " bash deploy/setup_env.sh" >&2 + exit 1 +} + +create_project_venv() { + local py="$1" + if [[ "${RECREATE_VENV}" -eq 1 && -d .venv ]]; then + echo " 删除旧 venv ..." + rm -rf .venv + fi + if [[ -d .venv && ! -x .venv/bin/python ]]; then + echo " 清理未完成的 venv ..." + rm -rf .venv + fi + if [[ -x .venv/bin/python ]]; then + return 0 + fi + echo " 创建 venv ..." + if ! "${py}" -m venv .venv; then + rm -rf .venv 2>/dev/null || true + echo " venv 创建失败" >&2 + exit 1 + fi +} + setup_monitor() { local dir_name="$1" local proj="${REPO_ROOT}/${dir_name}" @@ -92,16 +176,7 @@ setup_monitor() { fi step "${dir_name}" cd "${proj}" - local py - py="$(find_python)" - if [[ "${RECREATE_VENV}" -eq 1 && -d .venv ]]; then - echo " 删除旧 venv ..." - rm -rf .venv - fi - if [[ ! -x .venv/bin/python ]]; then - echo " 创建 venv ..." - "${py}" -m venv .venv - fi + create_project_venv "${PY}" echo " 升级 pip ..." .venv/bin/python -m pip install -U pip setuptools wheel -q echo " 安装依赖 ..." @@ -128,14 +203,7 @@ setup_hub() { fi step "manual_trading_hub" cd "${proj}" - local py - py="$(find_python)" - if [[ "${RECREATE_VENV}" -eq 1 && -d .venv ]]; then - rm -rf .venv - fi - if [[ ! -x .venv/bin/python ]]; then - "${py}" -m venv .venv - fi + create_project_venv "${PY}" .venv/bin/python -m pip install -U pip setuptools wheel -q if [[ -f "${HUB_REQ}" ]]; then .venv/bin/pip install -r "${HUB_REQ}" -q @@ -172,6 +240,7 @@ echo "仓库根目录: ${REPO_ROOT}" PY="$(find_python)" check_python_version "${PY}" +ensure_venv_prereqs "${PY}" should_include binance && setup_monitor crypto_monitor_binance should_include gate && setup_monitor crypto_monitor_gate