#!/usr/bin/env bash echoros_main() ( set -eu umask 077 export FISHROS_URL="${FISHROS_URL:-https://install.marinaecho.space}" case "$FISHROS_URL" in https://*) ;; *) printf '安装源必须使用 HTTPS\n' >&2; exit 1 ;; esac command -v apt-get >/dev/null || { printf '仅支持 Debian/Ubuntu 系统\n' >&2; exit 1; } SUDO='' if [ "$(id -u)" -ne 0 ]; then command -v sudo >/dev/null || { printf '请先安装 sudo 或使用 root 运行\n' >&2; exit 1; } SUDO=sudo sudo -v fi if ! command -v sudo >/dev/null || ! command -v python3 >/dev/null || ! python3 -c 'import yaml, distro' 2>/dev/null || [ ! -s /etc/ssl/certs/ca-certificates.crt ]; then $SUDO apt-get update $SUDO apt-get install -y python3 python3-yaml python3-distro ca-certificates sudo fi python3 -c 'import sys; sys.exit(0 if sys.version_info >= (3, 8) else "需要 Python 3.8+(推荐 Ubuntu 20.04 或更新版本)")' workdir=$($SUDO mktemp -d /tmp/echoros.XXXXXXXX) trap '$SUDO rm -rf -- "$workdir"; printf "\033[0m"' EXIT trap 'exit 130' INT trap 'exit 143' TERM $SUDO env FISHROS_URL="$FISHROS_URL" FISHROS_WORKDIR="$workdir" PYTHONUTF8=1 python3 - <<'PY' import hashlib import json import os import urllib.request from urllib.parse import urlparse class SecureRedirect(urllib.request.HTTPRedirectHandler): def redirect_request(self, req, fp, code, msg, headers, newurl): if urlparse(newurl).scheme != 'https': raise ValueError('拒绝重定向到非 HTTPS 地址') return super().redirect_request(req, fp, code, msg, headers, newurl) opener = urllib.request.build_opener(SecureRedirect()) root = os.environ['FISHROS_WORKDIR'] prefix = os.environ['FISHROS_URL'].rstrip('/') def fetch(relative): with opener.open(prefix + '/' + relative, timeout=30) as response: return response.read() raw = fetch('manifest.json') manifest = json.loads(raw) with open(os.path.join(root, 'manifest.json'), 'wb') as output: output.write(raw) for relative in ['install.py', 'tools/base.py', 'tools/download.py', 'tools/translation/translator.py', 'tools/translation/assets/zh_CN.py', 'tools/translation/assets/en_US.py']: data = fetch(relative) if hashlib.sha256(data).hexdigest() != manifest['files'][relative]: raise ValueError('发布文件校验失败: ' + relative) path = os.path.join(root, relative) os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, 'wb') as output: output.write(data) PY # Keep the private workspace at 0700, but install system directories with normal permissions. umask 022 config_path="${FISH_INSTALL_CONFIG:-$PWD/fish_install.yaml}" if [ -f "$config_path" ]; then export FISH_INSTALL_CONFIG="$config_path"; else unset FISH_INSTALL_CONFIG; fi if [ -z "${FISH_INSTALL_CONFIG:-}" ] && ( : /dev/null; then exec 3