WWW.YOUINFO.SITE
标签聚合 Termux

/tag/Termux

LinuxDo 最新话题 · 2026-06-11 20:48:22+08:00 · tech

脚本 #!/data/data/com.termux/files/usr/bin/bash set -euo pipefail readonly SCRIPT_NAME="$(basename "$0")" readonly MIMO_PACKAGE_NAME="@mimo-ai/cli" readonly MIMO_PACKAGE_VERSION="${MIMO_CODE_VERSION:-${MIMOCODE_VERSION:-latest}}" readonly PREFIX_DIR="${PREFIX:-/data/data/com.termux/files/usr}" readonly HOST_MIMO_PATH="$PREFIX_DIR/bin/mimo" readonly MIMO_CLI_PKG_DIR="$PREFIX_DIR/lib/node_modules/@mimo-ai/cli" readonly MIMO_ARCH_PKG_NAME="@mimo-ai/mimocode-linux-arm64" readonly MIMO_ARCH_PKG_DIR="$PREFIX_DIR/lib/node_modules/$MIMO_ARCH_PKG_NAME" readonly TMP_ROOT="$HOME/tmp" readonly BACKUP_DIR="$TMP_ROOT/mimocode-backups" readonly WRAPPER_MARKER="# mimocode-termux-glibc-wrapper" # Resolved by install_mimo_package() after locating the real glibc ELF. MIMO_BINARY_PATH="" MIMO_RESOLVED_VERSION="" readonly C_BOLD_BLUE="\033[1;34m" readonly C_BOLD_GREEN="\033[1;32m" readonly C_BOLD_YELLOW="\033[1;33m" readonly C_BOLD_RED="\033[1;31m" readonly C_RESET="\033[0m" info() { printf '%b[INFO]%b %s\n' "$C_BOLD_BLUE" "$C_RESET" "$*"; } success() { printf '%b[ OK ]%b %s\n' "$C_BOLD_GREEN" "$C_RESET" "$*"; } warn() { printf '%b[WARN]%b %s\n' "$C_BOLD_YELLOW" "$C_RESET" "$*" >&2; } die() { printf '%b[ERR ]%b %s\n' "$C_BOLD_RED" "$C_RESET" "$*" >&2; exit 1; } usage() { cat <<EOF Usage: bash $SCRIPT_NAME What it does (glibc-runner mode, no proot): 1. Installs glibc-repo, refreshes apt metadata, installs glibc-runner. 2. Installs nodejs-lts + npm in Termux (if missing). 3. npm installs ${MIMO_PACKAGE_NAME} globally, then force-installs the ${MIMO_ARCH_PKG_NAME} native linux-arm64 package. 4. Skips MiMoCode's postinstall script because Termux Node reports process.platform='android' and the upstream script looks for a non-existent @mimo-ai/mimocode-android-arm64 package. 5. Replaces \$PREFIX/bin/mimo with a grun wrapper that runs the glibc ELF directly on Termux. Environment overrides: MIMO_CODE_VERSION npm package version/tag, default: ${MIMO_PACKAGE_VERSION} examples: latest, preview, 0.1.0, v0.1.0 MIMOCODE_VERSION alias for MIMO_CODE_VERSION Notes: - Official MiMoCode install docs: https://github.com/XiaomiMiMo/MiMo-Code - glibc-runner injects glibc via LD_LIBRARY_PATH; kernel calls are native. EOF } command_exists() { command -v "$1" >/dev/null 2>&1; } # ELF magic = 7f 45 4c 46; e_machine at offset 18 = 0xb7 for EM_AARCH64. is_valid_aarch64_elf() { local f="$1" [ -f "$f" ] || return 1 local magic machine magic=$(od -An -tx1 -N4 "$f" 2>/dev/null | tr -d ' \n') [ "$magic" = "7f454c46" ] || return 1 machine=$(od -An -tx1 -j18 -N1 "$f" 2>/dev/null | tr -d ' \n') [ "$machine" = "b7" ] } find_arch_binary() { local candidate for candidate in \ "$MIMO_ARCH_PKG_DIR/bin/mimo" \ "$MIMO_CLI_PKG_DIR/bin/.mimocode"; do if is_valid_aarch64_elf "$candidate"; then MIMO_BINARY_PATH="$candidate" return 0 fi done while IFS= read -r candidate; do if is_valid_aarch64_elf "$candidate"; then MIMO_BINARY_PATH="$candidate" return 0 fi done < <(find "$MIMO_ARCH_PKG_DIR" "$MIMO_CLI_PKG_DIR" -type f -size +10M 2>/dev/null) return 1 } ensure_tmp_root() { mkdir -p "$TMP_ROOT" [ -w "$TMP_ROOT" ] || die "Temp directory is not writable: $TMP_ROOT" export TMPDIR="$TMP_ROOT" } require_termux() { [ -d "$PREFIX_DIR" ] || die "This script must run in Termux." command_exists pkg || die "pkg not found. This script must run in Termux." if [ -r /proc/1/status ] && grep -q 'TracerPid:.*[1-9]' /proc/1/status 2>/dev/null; then warn "Detected non-zero TracerPid on PID 1 -- looks like a proot session." warn "Run this script from a plain Termux shell, not from inside proot-distro." fi } ensure_termux_package() { local package_name="$1" if dpkg -s "$package_name" >/dev/null 2>&1; then success "Termux package already installed: $package_name" return 0 fi info "Installing Termux package: $package_name" pkg install -y "$package_name" success "Installed Termux package: $package_name" } ensure_glibc_runner() { ensure_termux_package "glibc-repo" if ! apt-cache show glibc-runner >/dev/null 2>&1; then info "Refreshing apt metadata so glibc-repo becomes visible" pkg update -y || apt-get update -y || true fi ensure_termux_package "glibc-runner" command_exists grun || die "grun not found after installing glibc-runner." } ensure_nodejs() { if command_exists node && command_exists npm; then success "Termux node present: $(node --version), npm $(npm --version)" return 0 fi if dpkg -s nodejs >/dev/null 2>&1; then success "nodejs already installed" else ensure_termux_package "nodejs-lts" fi command_exists node && command_exists npm || die "node/npm not found after installing nodejs." } resolve_mimo_version() { local requested="$MIMO_PACKAGE_VERSION" if [ "$requested" != "latest" ]; then requested="${requested#v}" fi local pkg_spec="$MIMO_PACKAGE_NAME" if [ "$requested" != "latest" ]; then pkg_spec="${MIMO_PACKAGE_NAME}@${requested}" fi info "Resolving version for ${pkg_spec}" local resolved resolved=$(npm view "$pkg_spec" version 2>/dev/null | tail -n1) \ || die "Failed to resolve version for ${pkg_spec} via npm view" [[ "$resolved" =~ ^[0-9]+\.[0-9]+ ]] \ || die "npm view returned a bogus version: '$resolved'" MIMO_RESOLVED_VERSION="$resolved" } backup_existing_launcher() { mkdir -p "$BACKUP_DIR" [ -e "$HOST_MIMO_PATH" ] || return 0 if grep -Fq "$WRAPPER_MARKER" "$HOST_MIMO_PATH" 2>/dev/null; then success "glibc-runner wrapper already in place" return 0 fi local backup_path="$BACKUP_DIR/mimo.host-backup.$(date +%Y%m%d_%H%M%S)" cp -P "$HOST_MIMO_PATH" "$backup_path" success "Backed up existing launcher to $backup_path" } install_mimo_package() { resolve_mimo_version local main_version="$MIMO_RESOLVED_VERSION" local pinned_main="${MIMO_PACKAGE_NAME}@${main_version}" local arch_spec="${MIMO_ARCH_PKG_NAME}@${main_version}" info "Installing ${pinned_main} without upstream optional platform packages" npm install -g --force --ignore-scripts --omit=optional "$pinned_main" info "Installing ${arch_spec} for Termux via glibc-runner" npm install -g --force --ignore-scripts --os=linux --cpu=arm64 "$arch_spec" find_arch_binary || die "No valid aarch64 ELF found under $MIMO_ARCH_PKG_DIR. \ The arch package may not have unpacked correctly; inspect with: \ ls -la $MIMO_ARCH_PKG_DIR" success "MiMoCode native binary: $MIMO_BINARY_PATH ($(stat -c %s "$MIMO_BINARY_PATH" 2>/dev/null || echo '?') bytes)" } install_host_wrapper() { local tmp_wrapper tmp_wrapper="$(mktemp "$TMP_ROOT/mimo-grun.XXXXXX")" cat >"$tmp_wrapper" <<EOF #!/data/data/com.termux/files/usr/bin/sh $WRAPPER_MARKER mkdir -p "\$HOME/tmp" 2>/dev/null || true export TMPDIR="\${TMPDIR:-\$HOME/tmp}" exec grun "$MIMO_BINARY_PATH" "\$@" EOF chmod 755 "$tmp_wrapper" rm -f "$HOST_MIMO_PATH" mv "$tmp_wrapper" "$HOST_MIMO_PATH" chmod 755 "$HOST_MIMO_PATH" success "Installed Termux launcher: $HOST_MIMO_PATH" } verify_install() { info "Verifying binary via grun" grun "$MIMO_BINARY_PATH" --version info "Verifying Termux launcher" "$HOST_MIMO_PATH" --version local path_mimo="" path_mimo="$(command -v mimo 2>/dev/null || true)" if [ -n "$path_mimo" ] && [ "$path_mimo" != "$HOST_MIMO_PATH" ]; then warn "Your PATH resolves 'mimo' to $path_mimo, not $HOST_MIMO_PATH." warn "Move $PREFIX_DIR/bin earlier in PATH or remove the older launcher." fi success "MiMoCode setup completed (glibc-runner mode)" } main() { if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then usage exit 0 fi ensure_tmp_root require_termux ensure_glibc_runner ensure_nodejs backup_existing_launcher install_mimo_package install_host_wrapper verify_install cat <<EOF Run MiMoCode with: mimo Configuration: mode: glibc-runner (no proot) binary: $MIMO_BINARY_PATH launcher: $HOST_MIMO_PATH temp: $TMP_ROOT If the official installer previously added ~/.mimocode/bin before $PREFIX_DIR/bin, that older launcher may shadow this Termux wrapper. Troubleshooting: - If npm cannot resolve a preview version, install with: MIMO_CODE_VERSION=preview bash $SCRIPT_NAME - If subprocess errors mention libc/ld.so, the binary is loading Termux bionic libs via inherited LD_LIBRARY_PATH. Check glibc-runner docs. EOF } main "$@" 1 个帖子 - 1 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-06-02 12:49:04+08:00 · tech

最近一直在折腾termux,小龙虾,爱马仕什么的都有折腾,都能装上去,而且感觉也不咋占用内存,用了几天,突然发现除了多个远程控制貌似真没什么惊艳的功能 (对我个人来说,我本来就用的手机,要不要远程都要用手机) 所以就都卸载了 想着手机上还有这存货给你们分享下 claude cli 这个一般用咱们站点的公益站或者2api就行了,不过我用的2api感觉都不太稳定,qwen不,gcli2api,gemini啊什么的感觉都不太稳,就平时日常用解决一些我懒得动手的东西,比如看到什么好的项目我就直接发给他安装(就是需要一直点确认很烦,本来就在termux里面,我也不怕他给我搞破坏,镜像都有备份) 下载的方式是佬友的脚本,帖子我不记得了,有知道的可以贴下,我加上 install-claude-termux-glibc.txt (8.8 KB) 后缀改sh,自己执行就行了 codex 这个我用的不太多,但是架不住佬友给的太多了,codex给的量太大了,所以搞了个 npm install -g @mmmbuto /codex-cli-termux@latest gemini cli 讲道理按理说termux应该没什么人用gemini cli了,前段时候gemini貌似都无法安装 最近没什么稳定的cli了,所以尝试了下,发现官方的居然也可以直接安装了 这也没啥主要是完全免费不用自己搞api,太难了,我手里一堆不稳定的,唉,保留个稳定的吧 npm install -g @google /gemini-cli hermes 这个不做评价,我只能说我不喜欢用,刚看到文件里有这个脚本,顺便发一下 hermes.txt (91.4 KB) 也是改为sh,里面的链接我都加了加速链接,用官方的下的累死,最后,安装完ui会转圈,让ai帮你弄下 1 个帖子 - 1 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-29 00:26:12+08:00 · tech

各位佬友好,求助一下。 我在 Termux 里安装了 Hermes Agent v0.14.0,执行 hermes gateway 的时候一直失败。 主要错误是: QQ Bot 获取 access token 失败:Failed to get QQ Bot access token: All connection attempts failed Telegram 连接超时(timed out after 30s) 我已经设置了代理: export ALL_PROXY= http://127.0.0.1:7890 用的代理是 Clash 和 Nekobox,也试过 --verbose 模式,还是不行。 另外 curl http://127.0.0.1:9090/configs 也连不上。 请问在 Termux 里跑 Hermes 需要什么特殊配置吗? 是不是还要额外启动什么本地服务?Clash Meta 和 Nekobox 要怎么配合才对? 谢谢佬们帮忙看看! 1 个帖子 - 1 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-29 00:16:00+08:00 · tech

本帖使用社区开源推广,符合推广要求。我申明并遵循社区要求的以下内容: 我的帖子已经打上 开源推广 标签: 是 我的开源项目完整开源,无未开源部分: 是 我的开源项目已链接认可 LINUX DO 社区: 是 我帖子内的项目介绍,AI生成、润色内容部分已截图发出: 是 以上选择我承诺是永久有效的,接受社区和佬友监督: 是 以下为项目介绍正文内容,AI生成、润色内容已使用截图方式发出 本程序为朋友 naiyQAQ 开发,由于没有ld账号由我授权代发 现在在termux运行cc的方式都比较麻烦且庞大,所以这里开发了可以在termux使用原生bun运行的claudecode [!warning] 请不要在本客户端登录官方账号,由于a÷魔改了bun所以导致发送的请求有变化,本项目使用原生bun运行,可能会导致严重风控! 依赖库: bun rg alsa-lib unzip 一键安装依赖: apt update apt install ripgrep alsa-lib unzip curl -y export _pwd=$(pwd) cd $PREFIX/tmp curl -L https://github.com/oven-sh/bun/releases/latest/download/bun-linux-aarch64-android.zip > bun.zip unzip -j bun.zip '*/bun' -d $PREFIX/bin && chmod +x $PREFIX/bin/bun cd $_pwd 项目本体 运行方式 从 Releases 页面下载最新的 anthropic-ai-claude-code-<version>-termux.tgz ,然后在本地执行(文中路径替换为上面你下载好的tgz路径): npm i -g @anthropic-claude/[email protected] npm i -g /path/to/your/tgz/file claude --version 如果显示 2.1.153 (Claude Code) 就可以愉快的使用claudecode了 enjoy! 所用代码开源地址 github.com GitHub - naiyQAQ/claude-code-termux: Native Claude Code on Termux — no... Native Claude Code on Termux — no proot/glibc-runner, powered by the Bun runtime. 5 个帖子 - 2 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-27 18:47:23+08:00 · tech

本期主题:termux永久唤醒 & ubuntu环境自启动 & 实现sshd 前五期回顾: 【超详细】手机搭建服务器 · 第 一 期 【超详细】手机搭建服务器 · 第 二 期 【超详细】手机搭建服务器 · 第 三 期 【超详细】手机搭建服务器 · 第 四 期 【超详细】手机搭建服务器 · 第 五 期 一、termux永久唤醒: 1. 打开MT管理器,进入 /data/adb/service.d/ 文件夹,创建 60-termux-wake-keeper.sh 开机脚本: #!/system/bin/sh # ============================================================ # 60-termux-wake-keeper.sh # # 功能: # 1. 手机开机后自动启动 termux-wake-keeper.sh # 2. 定时执行 termux-wake-lock,保持 wake lock # # 注意: # - 这个脚本只负责“开机拉起守护脚本” # - 真正循环执行 termux-wake-lock 的逻辑在: # /data/local/termux-wake-keeper/termux-wake-keeper.sh # ============================================================ BASE_DIR="/data/local/termux-wake-keeper" SCRIPT="$BASE_DIR/termux-wake-keeper.sh" LOG="$BASE_DIR/termux-wake-keeper-start.log" mkdir -p "$BASE_DIR" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG" } log "============================================================" log "===== termux wake keeper auto start | START =====" log "BASE_DIR=$BASE_DIR" log "SCRIPT=$SCRIPT" log "LOG=$LOG" # ------------------------------------------------------------ # 1. 等待 Android 系统启动完成 # ------------------------------------------------------------ while [ "$(getprop sys.boot_completed)" != "1" ]; do sleep 5 done log "Android boot completed" # ------------------------------------------------------------ # 2. 再额外等待一会儿 # 避免刚开机时 /data/data、Termux、ZeroTermux 相关环境还没完全稳定 # ------------------------------------------------------------ sleep 30 # ------------------------------------------------------------ # 3. 检查主守护脚本是否存在 # ------------------------------------------------------------ if [ ! -x "$SCRIPT" ]; then log "ERROR: script not found or not executable: $SCRIPT" log "Please check file path and chmod 755." log "===== termux wake keeper auto start | FAILED =====" exit 1 fi # ------------------------------------------------------------ # 4. 启动守护脚本 # 守护脚本内部有 PID 判断,重复启动不会产生多个实例 # ------------------------------------------------------------ nohup "$SCRIPT" >> "$LOG" 2>&1 & log "termux wake keeper started" log "===== termux wake keeper auto start | DONE =====" log "============================================================" 2.在 /data/local/termux-wake-keeper/ 文件夹中创建termux-wake-keeper.sh脚本 #!/system/bin/sh # ============================================================ # termux-wake-keeper.sh # # 功能: # 1. 定时执行 termux-wake-lock # 2. 防止 wake lock 失效 # 3. 不依赖 Ubuntu # 4. 不启动 sshd / nginx # # 日志: # /data/local/termux-wake-keeper/termux-wake-keeper.log # ============================================================ BASE_DIR="/data/local/termux-wake-keeper" LOG="$BASE_DIR/termux-wake-keeper.log" RUN_DIR="/dev/.termux-wake-keeper" PIDFILE="$RUN_DIR/termux-wake-keeper.pid" # 每隔多少秒重新执行一次 termux-wake-lock INTERVAL="60" mkdir -p "$BASE_DIR" mkdir -p "$RUN_DIR" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG" } is_running() { OLD_PID="$1" if [ -z "$OLD_PID" ]; then return 1 fi if [ ! -d "/proc/$OLD_PID" ]; then return 1 fi tr '\0' ' ' < "/proc/$OLD_PID/cmdline" 2>/dev/null | grep -q "termux-wake-keeper.sh" } find_wake_lock_cmd() { for p in \ /data/data/com.termux/files/usr/bin/termux-wake-lock \ /data/data/com.zerotermux/files/usr/bin/termux-wake-lock \ /data/data/com.termux.zero/files/usr/bin/termux-wake-lock do if [ -x "$p" ]; then echo "$p" return 0 fi done find /data/data -path '*/files/usr/bin/termux-wake-lock' -type f -perm -111 2>/dev/null | head -n 1 } find_wake_unlock_cmd() { for p in \ /data/data/com.termux/files/usr/bin/termux-wake-unlock \ /data/data/com.zerotermux/files/usr/bin/termux-wake-unlock \ /data/data/com.termux.zero/files/usr/bin/termux-wake-unlock do if [ -x "$p" ]; then echo "$p" return 0 fi done find /data/data -path '*/files/usr/bin/termux-wake-unlock' -type f -perm -111 2>/dev/null | head -n 1 } # 防止重复启动 if [ -f "$PIDFILE" ]; then OLD_PID="$(cat "$PIDFILE" 2>/dev/null)" if is_running "$OLD_PID"; then log "already running, pid=$OLD_PID" exit 0 else log "stale pidfile found, overwrite" fi fi echo "$$" > "$PIDFILE" WAKE_LOCK_CMD="$(find_wake_lock_cmd)" WAKE_UNLOCK_CMD="$(find_wake_unlock_cmd)" log "============================================================" log "===== termux wake keeper | START =====" log "PID=$$" log "BASE_DIR=$BASE_DIR" log "LOG=$LOG" log "INTERVAL=$INTERVAL" log "WAKE_LOCK_CMD=$WAKE_LOCK_CMD" log "WAKE_UNLOCK_CMD=$WAKE_UNLOCK_CMD" if [ -z "$WAKE_LOCK_CMD" ]; then log "ERROR: termux-wake-lock not found" log "Please check: find /data/data -path '*/files/usr/bin/termux-wake-lock'" rm -f "$PIDFILE" exit 1 fi release_lock() { log "release termux wake lock" if [ -n "$WAKE_UNLOCK_CMD" ] && [ -x "$WAKE_UNLOCK_CMD" ]; then "$WAKE_UNLOCK_CMD" >> "$LOG" 2>&1 log "termux-wake-unlock executed" else log "WARN: termux-wake-unlock not found, skip unlock" fi rm -f "$PIDFILE" } trap 'release_lock; exit 0' INT TERM # 启动时先执行一次 "$WAKE_LOCK_CMD" >> "$LOG" 2>&1 RESULT="$?" if [ "$RESULT" = "0" ]; then log "termux-wake-lock executed at startup" else log "ERROR: termux-wake-lock startup failed, result=$RESULT" fi # 循环续保 while true; do sleep "$INTERVAL" "$WAKE_LOCK_CMD" >> "$LOG" 2>&1 RESULT="$?" if [ "$RESULT" = "0" ]; then log "termux-wake-lock refresh ok" else log "ERROR: termux-wake-lock refresh failed, result=$RESULT" fi done [!note]如何手动停止唤醒 如果需要手动停止唤醒,可以用下面这个脚本,如果不需要,可以忽略,一般是不需要的 stop-termux-wake-keeper.sh: #!/system/bin/sh # ============================================================ # stop-termux-wake-keeper.sh # # 功能: # 1. 停止 termux-wake-keeper.sh 守护脚本 # 2. 执行 termux-wake-unlock # # 日志: # /data/local/termux-wake-keeper/termux-wake-keeper.log # ============================================================ BASE_DIR="/data/local/termux-wake-keeper" LOG="$BASE_DIR/termux-wake-keeper.log" RUN_DIR="/dev/.termux-wake-keeper" PIDFILE="$RUN_DIR/termux-wake-keeper.pid" mkdir -p "$BASE_DIR" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG" } find_wake_unlock_cmd() { for p in \ /data/data/com.termux/files/usr/bin/termux-wake-unlock \ /data/data/com.zerotermux/files/usr/bin/termux-wake-unlock \ /data/data/com.termux.zero/files/usr/bin/termux-wake-unlock do if [ -x "$p" ]; then echo "$p" return 0 fi done find /data/data -path '*/files/usr/bin/termux-wake-unlock' -type f -perm -111 2>/dev/null | head -n 1 } log "============================================================" log "===== stop termux wake keeper | START =====" if [ -f "$PIDFILE" ]; then PID="$(cat "$PIDFILE" 2>/dev/null)" if [ -n "$PID" ] && [ -d "/proc/$PID" ]; then kill -TERM "$PID" log "sent TERM to termux-wake-keeper pid=$PID" sleep 1 else log "pid not running: $PID" fi rm -f "$PIDFILE" else log "pidfile not found: $PIDFILE" fi WAKE_UNLOCK_CMD="$(find_wake_unlock_cmd)" log "WAKE_UNLOCK_CMD=$WAKE_UNLOCK_CMD" if [ -n "$WAKE_UNLOCK_CMD" ] && [ -x "$WAKE_UNLOCK_CMD" ]; then "$WAKE_UNLOCK_CMD" >> "$LOG" 2>&1 RESULT="$?" if [ "$RESULT" = "0" ]; then log "termux-wake-unlock executed" else log "ERROR: termux-wake-unlock failed, result=$RESULT" fi else log "WARN: termux-wake-unlock not found" fi log "===== stop termux wake keeper | DONE =====" log "============================================================" [!warning]提醒 上面的脚本一定要记得给足权限 二、实现ubuntu开机自启 1. 打开MT管理器,进入 /data/adb/service.d/ 文件夹,新建文件 90-ubuntu-sshd.sh ,代码如下: #!/system/bin/sh # ============================================================ # 90-ubuntu-sshd.sh # # 功能: # 1. 开机后调用 Magisk 版 chroot-distro # 2. 自动准备 ubuntu chroot 环境 # 3. 自动启动 ubuntu 里的 sshd # # 说明: # - 不处理 wake lock # - 不依赖 Termux 路径 # - 不在脚本里写死 SSH 端口 # - SSH 端口以 Ubuntu 的 /etc/ssh/sshd_config 为准 # ============================================================ # 日志目录 LOG_DIR="/data/local/chroot-distro/logs" # 日志文件 LOG="$LOG_DIR/ubuntu-sshd-start.log" # 你平时是 chroot-distro login ubuntu # 所以这里发行版名称就是 ubuntu DISTRO="ubuntu" # 开机后额外等待时间 BOOT_WAIT="25" # 设置 Android / Magisk 常见命令路径 # 这个不是 Termux PATH,只是为了让 service.d 脚本能找到系统命令 export PATH="/system/bin:/system/xbin:/vendor/bin:/odm/bin:/data/adb/magisk:/data/adb/ksu/bin:$PATH" # 确保日志目录存在 mkdir -p "$LOG_DIR" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG" } log "============================================================" log "===== Ubuntu sshd auto start via chroot-distro | START =====" log "DISTRO=$DISTRO" log "BOOT_WAIT=$BOOT_WAIT" log "LOG=$LOG" # ------------------------------------------------------------ # 1. 等待 Android 开机完成 # ------------------------------------------------------------ while [ "$(getprop sys.boot_completed)" != "1" ]; do sleep 5 done log "Android boot completed" sleep "$BOOT_WAIT" # ------------------------------------------------------------ # 2. 查找 chroot-distro # ------------------------------------------------------------ CHROOT_DISTRO="$(command -v chroot-distro 2>/dev/null)" if [ -z "$CHROOT_DISTRO" ]; then if [ -x /system/bin/chroot-distro ]; then CHROOT_DISTRO="/system/bin/chroot-distro" elif [ -x /system/xbin/chroot-distro ]; then CHROOT_DISTRO="/system/xbin/chroot-distro" else log "ERROR: chroot-distro command not found" log "Please run: command -v chroot-distro" log "===== FAILED =====" exit 1 fi fi log "CHROOT_DISTRO=$CHROOT_DISTRO" # ------------------------------------------------------------ # 3. 让 chroot-distro 准备 Ubuntu 环境 # ------------------------------------------------------------ log "mount distro: $DISTRO" "$CHROOT_DISTRO" mount "$DISTRO" >> "$LOG" 2>&1 # ------------------------------------------------------------ # 4. 在 Ubuntu 环境里启动 sshd # ------------------------------------------------------------ log "start sshd inside Ubuntu" "$CHROOT_DISTRO" command "$DISTRO" ' mkdir -p /run/sshd chmod 755 /run/sshd ssh-keygen -A >/dev/null 2>&1 || true /usr/sbin/sshd -t if [ $? -ne 0 ]; then echo "ERROR: sshd config test failed" exit 1 fi echo "effective sshd config:" /usr/sbin/sshd -T | awk "/^(port|addressfamily|listenaddress|permitrootlogin|passwordauthentication|pubkeyauthentication) / {print}" if pgrep -x sshd >/dev/null 2>&1; then echo "sshd already running" else /usr/sbin/sshd echo "sshd started" fi ' >> "$LOG" 2>&1 RESULT="$?" if [ "$RESULT" != "0" ]; then log "ERROR: chroot-distro command failed, result=$RESULT" log "===== Ubuntu sshd auto start via chroot-distro | FAILED =====" exit 1 fi log "chroot-distro command finished" # ------------------------------------------------------------ # 5. 输出监听状态 # 不写死端口,直接看 sshd 实际监听了什么 # ------------------------------------------------------------ log "listening status:" ss -lntp 2>/dev/null | grep sshd >> "$LOG" 2>&1 log "process status:" ps -A 2>/dev/null | grep sshd >> "$LOG" 2>&1 log "===== Ubuntu sshd auto start via chroot-distro | DONE =====" log "============================================================" [!warning]权限提醒 脚本同样记得给足权限 三、如何在ubuntu中实现sshd 1.修改 sshd 配置 打开mt管理器 /data/local/chroot-distro/ubuntu/etc/ssh/sshd_config , 修改 sshd_config文件: 找到这段代码: #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: 改成 Port 2222 AddressFamily any ListenAddress 0.0.0.0 ListenAddress :: 再找到 # PasswordAuthentication yes 改成 PasswordAuthentication yes PubkeyAuthentication yes 也就是密码和允许使用 SSH 密钥登录 2.创建 sshd 运行目录 sudo mkdir -p /run/sshd sudo chmod 755 /run/sshd 3.启动 sshd 如果有旧的ssh,就先停掉旧的 sshd: sudo pkill sshd 2>/dev/null 再启动: sudo /usr/sbin/sshd 确认是否监听成功: ss -lntp | grep sshd 正常应该看到类似: LISTEN 0 128 [::]:2222 [::]:* users:(("sshd",pid=xxxx,fd=3)) 这说明 Ubuntu 已经在 IPv6 的 2222 端口上等待外部连接。 给几个常用的命令: 查看sshd状态: ss -lntp | grep sshd 停止: pkill -TERM -x sshd 启动: mkdir -p /run/sshd && chmod 755 /run/sshd && /usr/sbin/sshd 重启: /usr/sbin/sshd -t && pkill -TERM -x sshd && sleep 1 && mkdir -p /run/sshd && chmod 755 /run/sshd && /usr/sbin/sshd [!warning]远端ssh报错问题 如果远端ssh访问时,有下面这张报错问题: -bash: /etc/bash.bashrc: Required key not available -bash: /home/semmering/.profile: Required key not available -bash-5.2$ 解决办法是: 用MT管理器,把 /data/local/chroot-distro/ubuntu/etc/pam.d/sshd 这句话注销就不会报错了。 # session optional pam_keyinit.so force revoke 也就是在这句话前面加上#号,或者删除这句话。 这个报错问题非常不好解决,网络上的信息非常少。非常幸运再github上找到了方法。 [!success] 按照上面的教程来一步一步操作。脚本记得给足权限,然后重新开关机,termux会永久唤醒,然后ubuntu环境也会准备好,然后sshd也会准备好,就可以实现远端通过域名访问了。 3 个帖子 - 3 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-27 00:58:33+08:00 · tech

我经常在手机上用termux倒腾一点东西嘛,这几年来来去去玩的东西不少,不过留下来的不多 下面给大家汇总介绍一些 在这里提醒一下,手机本身散热就不大行,加上供电需要改;如果纯软件上也要root,说实话软件控制效果不好,要长期玩还是得改硬件供电、散热,或者日常只开着几个服务,这里介绍的不涉及root,只要你手机能装termux就能用; 我这套配置在局域网下是可以正常运行的,当然不是全开,日常就 couchdb 开着同步obsidian, nginx 开着做导航, vaultwarden+sqlite 开着; llamacpp开着Bge-m3-Q8.gguf 但是很少运行, sqlite 可以换成 MySQL 如果你同时开着 NextCloud 的话,不过nextcloud的云盘功能很大程度上被obsidian的同步给替换了,毕竟nextcloud要同时开着 apache2 | mariadb-server | nextcloud | nginx 嘛,相对来说太繁夯了; 佬们,日常用的前提必须是稳的、稳定、稳定;如果不改供电和散热的话不要贪多,只开两三个就可以了,而且定期重启一下,或者换平板来,实测比手机强的多。 设备是 一加8T(soc865 12+256) 日常25-30℃,不会太烫,有新文件向量处理的时候会烫一会,但是日常小文件完全没问题,如果有大量文件还是别折磨手机了, 真的会炸 通过couchdb做obsidian的同步方案 使用llamacpp来部署个 Bge-m3 向量模型来给obsidian的笔记用 vaultwarden密码管理器 局域网下假域名 使用comfyui部署Z-Image-Turbo来绘图 NextCloud自部署网盘 MySQL数据库 介绍从termux原始环境中部署的开始,如果你跳转到后边发现有依赖缺失可以到前边找找 termux初始化 termux从GitHub直接下 termux-GitHub 1. 需要用到的软件 我刚接触是跟着国光大佬的教程学的,但是我对终端美化没什么需求,就没改动,可以搜搜大佬的教程,可以下 zsh 之类的把终端改的很好看 # 选一个China或者Asian的源,方便 termux-change-repo # 更新一下先 pkg update && pkg upgrade -y # 加一些可能用到的源 pkg install tur-repo root-repo -y # 安装一些需要的软件 pkg install vim wget nginx tmux git git-lfs proot-distro uv unzip curl cmake npm -y 2. 安装Debian容器 termux的proot-distro更新后好像改了很多东西, # Version 5.0 release notes 用法上没什么改变,但是好像有些东西会报错 ## 下载Debian:12 # 这里可以开代理,会快很多 proot-distro install debian:12 # 进入 proot-distro login debian # 可以直接写个 bash脚本,能少敲几个词语 touch login_debian.sh echo 'proot-distro login debian' > login_debian.sh chmod +x login_debian.sh ./login_debian.sh 3. proot-distro容器与termux文件互传 因为proot-distro是个容器嘛,与termux原始环境是隔离的; 通过ln 建个链接可以把个目录在termux与proot-distro间联通 ## 这里是termux的~/目录,可以随便取名字 mkdir TheFiles cd TheFiles && pwd # >>得到地址,一般是 /data/data/com.termux/files/home/TheFiles ## 进入到了proot-distro容器的环境 # 目录是 /root/ # 当然如果你习惯用其他的目录位置也都可以 ln -s /data/data/com.termux/files/home/TheFiles ./ # 然后就可以在/root/目录下看到该目录了,这个目录是termux环境和proot-distro容器之间互通的,文件的更改也是同步的 # 在这里提醒一句,最好不要su获取root之后再进入proot-distro环境,这会导致很多文件的归属问题,不知道会有什么奇奇怪怪的bug 假域名 有这个需求是因为如果你的设备需要移动,接入不同的WiFi时自动分配的IP肯定会变,IP一变化很多东西都要重新绑定很麻烦 可以用python的工具 1. 用uv创建个python环境 # 先创建个目录,比如mdns啥的 # 然后再该目录下创建环境 uv venv # 进入python环境 source .venv/bin/activate 1.1 安装一下几个包 uv pip install ifaddr netifaces zeroconf 2. 创建文件 这里分成了两个, python文件是运行的,配置文件是config.json 文件你可以让AI给你改,很方便 2.1 mdns_auto.py import json import socket import netifaces from time import sleep from zeroconf import Zeroconf, ServiceInfo def get_interface_ip(interface_name="wlan2"): try: iface = netifaces.ifaddresses(interface_name) ipv4_info = iface[netifaces.AF_INET][0] return ipv4_info["addr"] except Exception as e: raise RuntimeError( f"Cannot get IP for interface: {interface_name}" ) from e # ============================================ # 加载配置文件 # ============================================ with open("config.json", "r") as f: config = json.load(f) # ============================================ # 获取 hostname # ============================================ hostname = config["hostname"] # ============================================ # 获取本机 IP # ============================================ #local_ip = get_local_ip() local_ip = get_interface_ip("wlan2") print(f"[INFO] Local IP: {local_ip}") # ============================================ # 启动 Zeroconf # ============================================ #zeroconf = Zeroconf() zeroconf = Zeroconf( interfaces=[local_ip] ) # ============================================ # 已注册服务列表 # ============================================ registered_services = [] # ============================================ # 遍历所有服务 # ============================================ for svc in config["services"]: name = svc["name"] service_type = svc["type"] port = svc["port"] path = svc["path"] description = svc["description"] full_service_name = f"{name}.{service_type}" print(f"[REGISTER] {name}:{port}") info = ServiceInfo( service_type, full_service_name, addresses=[socket.inet_aton(local_ip)], port=port, properties={ "path": path, "description": description, "server": hostname, "port": str(port) }, server=hostname, ) zeroconf.register_service(info) registered_services.append(info) print("[INFO] All services registered.") # ============================================ # 保持运行 # ============================================ try: while True: sleep(1) except KeyboardInterrupt: print("\n[INFO] Stopping services...") finally: # ======================================== # 注销所有服务 # ======================================== for svc in registered_services: zeroconf.unregister_service(svc) zeroconf.close() print("[INFO] Zeroconf stopped.") ~/AIFiles/mdns $ cat config.json 2.2 config.json示例如下 { "hostname": "your_self_doim.local.", "services": [ { "name": "WebPortal", "type": "_http._tcp.local.", "port": 8077, "path": "/", "description": "Web Navigation Portal" }, { "name": "CouchDB", "type": "_http._tcp.local.", "port": 5984, "path": "/", "description": "CouchDB Database" }, { "name": "LlamaCPP", "type": "_http._tcp.local.", "port": 8888, "path": "/v1/models", "description": "llama.cpp OpenAI API" }, { "name": "ComfyUI", "type": "_http._tcp.local.", "port": 7777, "path": "/", "description": "ComfyUI WebUI" }, { "name": "VSCodeServer", "type": "_http._tcp.local.", "port": 8080, "path": "/", "description": "VSCode Server" }, { "name": "ZeroClaw", "type": "_http._tcp.local.", "port": 8833, "path": "/", "description": "ZeroClaw WebUI" }, { "name": "SillyTavern", "type": "_http._tcp.local.", "port": 9988, "path": "/", "description": "SillyTavern UI" } ] } 运行 只需要开个tmux窗口然后在后台挂着就可以了 uv run python mdns_auto.py 这里的配置是假定你用该设备共享热点 llama.cpp部署并运行本地模型 1 编译安装 1.1 克隆项目 # 这里目录随意 git clone https://github.com/ggml-org/llama.cpp.git 1.2 编译 # 这里在llama.cpp项目目录下 cmake -B build cmake --build build/ --config Release -j4 1.3 llama-server等添加到环境变量 把这两行添加到环境变量 ## llama.cpp环境变量 export LD_LIBRARY_PATH=/data/data/com.termux/files/home/<your Path>/llama.cpp/build/bin:$LD_LIBRARY_PATH export PATH=/data/data/com.termux/files/home/<your-Path>/llama.cpp/build/bin:$PATH 刷新一下,然后就可以在termux随地使用 llama-cli | llama-server 等命令了 这里补充一下, llama-cli/llama-server 在运行时,可以用 -t1 -t2 -tn (n取小于你soc核心数的正整数) 等参数来选择调用的核心数量,手机的核心大小不一,只用大核心比全弄效果好很多。 nginx配置 nginx安装后,相关的配置文件在 $PREFIX/usr/etc/nginx/ 目录下; 配置和正常Linux一样,只是 include xxx.conf 引用配置的时候尽量用绝对目录,有时候容易出毛病,或者建个 conf.d 目录,直接用 include xxxxx/conf.d/*.conf 引用目录下文件,方便一点 可以用su获取root之后再运行,这样可以用1000以下的端口,如果不用root也能正常用,注意不要用1000以下的端口,因为没有权限 下面开始进入proot-distro容器部分 最好不要su获取root后进入proot-distro,会因为文件归属问题有时候会有奇奇怪怪的bug CouchDB数据库 1. couchdb数据库的安装 参照couchdb官方的示例 官方文档 1.1 添加官方的库 ## 其实我不太懂,不过官方文档是这么写的 # 1 apt update && apt install -y curl apt-transport-https gnupg # 2 curl https://couchdb.apache.org/repo/keys.asc | gpg --dearmor | tee /usr/share/keyrings/couchdb-archive-keyring.gpg >/dev/null 2>&1 # 3 source /etc/os-release # 4 echo "deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main" \ | tee /etc/apt/sources.list.d/couchdb.list >/dev/null 1.2 安装 # 先搜索一下确认库添加上了 apt search couchdb # 应该会新增这仨 couchdb/bookworm 3.5.2~bookworm arm64 RESTful document oriented database couchdb-dbgsym/bookworm 3.5.0~bookworm arm64 debug symbols for couchdb couchdb-nouveau/bookworm 3.5.2~bookworm arm64 Nouveau adds Lucene capabilities to CouchDB ## 用apt安装 apt install couchdb 1.3 couchdb初始化 这是紧接着安装之后,他会引导你初始化一些配置,安装好后在web界面都可以图形化配置 Configuring couchdb ------------------- Please select the CouchDB server configuration type that best meets your needs. For single-server configurations, select standalone mode. This will set up CouchDB to run as a single server. For clustered configuration, select clustered mode. This will prompt for additional parameters required to configure CouchDB in a clustered configuration. If you prefer to configure CouchDB yourself, select none. You will then need to edit /opt/couchdb/etc/vm.args and /opt/couchdb/etc/local.d/*.ini yourself. Be aware that this will bypass *all* configuration steps, including setup of a CouchDB admin user. You'll have to create one manually. 1. standalone 2. clustered 3. none ## 这里是问你1.单机运行 2.多机集群配置 3.等等再说 ,我是单机所以就直接1了 General type of CouchDB configuration: 1 A CouchDB node has an Erlang magic cookie value set at startup. This value must match for all nodes in the cluster. If they do not match, attempts to connect the node to the cluster will be rejected. ## 配置神奇曲奇(bushi)我理解是密码一类的东西,是不显示的,输入完成之后回车就可以 CouchDB Erlang magic cookie: [your password] A CouchDB node must bind to a specific network interface. This is done via IP address. Only a single address is supported at this time. The special value '0.0.0.0' binds CouchDB to all network interfaces. The default is 127.0.0.1 (loopback) for standalone nodes, and 0.0.0.0 (all interfaces) for clustered nodes. In clustered mode, it is not allowed to bind to 127.0.0.1. ## 这里问你是只允许127.0.0.1访问还是都允许,虽然说单个人的数据没什么太大的盗取价值,不过还是建议用127.0.0.1然后加个nginx反代 CouchDB interface bind address: 127.0.0.1 It is highly recommended that you create a CouchDB admin user, which takes CouchDB out of the insecure "admin party" mode. Entering a password here will take care of this step for you. If this field is left blank, an admin user will not be created. A pre-existing admin user will not be overwritten by this package. ## 这才是真正的账号-密码,当然初始化是管理员的账号密码,同样是隐藏的,直接输入完成后回车就可以,这里要多确认一次 Password for the CouchDB "admin" user: Repeat password for the CouchDB "admin" user: invoke-rc.d: could not determine current runlevel invoke-rc.d: policy-rc.d denied execution of start. WARNING: Unable to create standalone system databases. CouchDB may not have started correctly (no init?) Once CouchDB has started correctly, run the following: curl -X PUT --user '<admin-user>:<admin-pass>' http://127.0.0.1:5984/_users curl -X PUT --user '<admin-user>:<admin-pass>' http://127.0.0.1:5984/_replicator Processing triggers for libc-bin (2.36-9+deb12u14) ... 到这里就部署完成了,可以在 http://127.0.0.1:5984/_utls 页面查看后台管理页面 obsidian的设置可以在电脑端配置完后直接用二维码导入到手机,这样可以方便一点,毕竟手机的UI比较小,适配也不一定很合适,但是同步方面我在局域网下使用完全没有问题. 顺带说一下,我Obsidian使用的AI插件是站内大佬的YOLO,挺好用的; 同步使用的是self-host live sync插件 MySQL数据库 这个好装,在proot-distro里叫 mariadb 1. 安装 # 默认的源就带着,直接装就行 apt update && apt install mariadb-server -y 2. 使用 # 启动服务 service mariadb start # 然后就可以直接进入了 mysql 进入MySQL数据库环境之后的具体使用,小弟在这里就不班门弄斧了,只贴一下简单的常用命令 # 登录 MySQL # 登录指定name的账户,<CR>后输入密码 mysql -u name -p # 登录默认账户root mysql # 查看正在运行的数据库 SHOW DATABASES; # 查看特定数据库的信息 USE 数据库名; SHOW TABLES; # 确认当前使用的数据库 SELECT DATABASE(); # 查看正在使用的端口 SHOW VARIABLES LIKE 'port'; # 这个端口在`/etc/mysql/`下的 `my.cnf`中,默认是3306,可以改 # 改完之后重启运行就行 # 刷新MySQL权限相关的表 flush privileges; # 查看所有数据库用户要查看所有数据库用户,可以查询`mysql`数据库中的`user`表。 # 首先切换到`mysql`数据库: USE mysql; # 然后执行以下查询: SELECT User, Host FROM user; # 要查看用户`user`在数据库`nextcloud`上的权限 SHOW GRANTS FOR 'user'@'localhost' ON `nextcloud`.*; # 查询特定用户在特定主机上的权限 SHOW GRANTS FOR 'AIPING'@'localhost:7777'; # 更改指定用户的密码为 ALTER USER 'AIPING'@'localhost' IDENTIFIED BY 'new_password'; FLUSH PRIVILEGES; vaultwarden部署 1. 安装 下载地址 vaultwarden项目地址 web-vault项目地址 首先, vaultwarden 想要正常工作需要六个部分, vaultwarden web-vault nginx MySQL rustup vaultwarden 是bitwarden项目的社区版 Vaultwarden 是一个用于本地搭建 Bitwarden 服务器的第三方 Docker 项目。仅在部署的时候使用 Vaultwarden 镜像,桌面端、移动端、浏览器扩展等客户端均使用官方 Bitwarden 客户端。 web-vault 是web页面 nginx 提供代理服务 在局域网内还用 nginx 代理是因为不开https访问的话,网页只能在127.0.0.1上访问,在局域网内其他设备上使用的话会一直在首页转圈圈,当然,还是因为我只会用 nginx 搭建自签证书的https访问,所以就只介绍这个了; MySQL 用来提供数据库 当然官方也支持 Sqlite 等其他的类型,但是我之所以用 MySQL 只是因为我只会用这个,欸嘿,所以就介绍这一个了; rustup 是vaultwarden安装教程推荐的 rust table ,没怎么接触过,是按教程来的 1.1 安装依赖 apt install build-essential git pkg-config libssl-dev libmariadb-dev-compat libmariadb-dev -y # termux pkg install clang make pkg-config git openssl tur-repo -y 更新包列表并安装构建工具、Git、SSL 开发库 和 Certbot。 对于 MySQL,还需额外安装 MySQL 和开发库。 1.2 安装 Rust 使用官方 rustup 安装稳定版 Rust 和 Cargo。 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source $HOME/.cargo/env rustc --version # 验证安装,应显示 rustc 1.x.x 2. 构建 Vaultwarden 2.1 克隆源代码 创建一个源代码目录并克隆仓库。 mkdir ~/source && cd ~/source git clone https://github.com/dani-garcia/vaultwarden.git cd vaultwarden 2.2 构建二进制文件 根据数据库选择构建特性。 SQLite(默认,简单) : cargo build --features sqlite --release MySQL(推荐生产环境) : cargo build --features mysql --release # 示例:MySQL 构建(替换为你的选择) cargo build --features mysql --release 提示 :如果内存不足,添加 --jobs 1 限制并行任务。构建后,二进制文件在 ~/source/vaultwarden/target/release/vaultwarden 。 3. 配置 Vaultwarden 3.1 创建数据目录 创建专用目录并设置权限。 sudo mkdir -p /var/lib/vaultwarden cd /var/lib/vaultwarden sudo mkdir -p data sudo useradd -m -d /var/lib/vaultwarden vaultwarden # 创建专用用户 sudo chown -R vaultwarden:vaultwarden /var/lib/vaultwarden 3.2 下载环境模板和 Web Vault 下载配置文件模板和 Web 界面(推荐最新版本,检查 GitHub Releases 获取当前版本,例如 v2026.4.1)。 ## 目录/var/lib/vaultwarden # 下载环境模板 wget https://raw.githubusercontent.com/dani-garcia/vaultwarden/main/.env.template mv .env.template .env # 下载 Web Vault(示例版本,替换为最新) wget https://github.com/dani-garcia/bw_web_builds/releases/download/v2026.4.1/bw_web_v2026.4.1.tar.gz tar -xvf bw_web_v2026.4.1.tar.gz --strip-components=1 -C data/ # 其实删不删都行,不删留着也没多大,还能方便看是安装的哪个版本 rm bw_web_v2026.4.1.tar.gz 3.3 配置数据库 3.3.1 SQLite(默认) 无需额外步骤,直接在 .env 中使用默认路径。 3.3.2 MySQL(新增) 登录 MySQL 并创建数据库和用户: mysql -u root -p # 输入 root 密码 在 MySQL 提示符下运行: CREATE DATABASE vaultwarden CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'vaultwarden'@'localhost' IDENTIFIED BY 'your_strong_password'; GRANT ALL PRIVILEGES ON vaultwarden.* TO 'vaultwarden'@'localhost'; FLUSH PRIVILEGES; EXIT; 替换 your_strong_password 为强密码。 在 .env 中配置 MySQL 连接(见下文 3.4)。 3.4 编辑 .env 文件 使用编辑器配置环境变量。关键设置包括域名、数据库、日志和通知。 vim /var/lib/vaultwarden/.env 示例配置(SQLite 版) : 不用复制这个示例,直接在官方的example示例里寻找需要改的部分,需要改的示例如下,其他配置我没有用到,不懂(哥们不是IT出身,主打一个能用就像) DATA_FOLDER=data DATABASE_URL=DATABASE_URL=sqlite://data/db.sqlite3 # SQLite 默认路径 LOG_FILE=data/vaultwarden.log LOG_LEVEL=info # 生产环境用 error DOMAIN=https://your-domain.com # 你的域名 ROCKET_ADDRESS=127.0.0.1 ROCKET_PORT=8000 示例配置(MySQL 版) :仅替换 DATABASE_URL 行: DATA_FOLDER=data DATABASE_URL=mysql://vaultwarden:your_strong_password@localhost/vaultwarden # MySQL 连接字符串 # 其余配置同上 提示 :完整模板见 Vaultwarden 文档 。测试配置:保存后,重启服务验证。 4. 部署和运行 4.1 复制二进制文件 cp ~/source/vaultwarden/target/release/vaultwarden /usr/local/bin/vaultwarden chmod +x /usr/local/bin/vaultwarden 4.2 运行 # 目录为/var/lib/vaultwarden vaultwarden # 长时间运行可以用nohup或者tmux,我喜欢用tmux # nohup nohup vaultwarden & # tmux就是直接开个新tmux窗口运行 vaultwarden NextCloud 1.安装一些用到的软件 官方教程里用到的软件(这里我把 sudo 去掉了,因为本来就是root用户而且termux好像取得root有点费劲儿) apt update && apt upgrade apt install apache2 mariadb-server libapache2-mod-php php-gd php-mysql \ php-curl php-mbstring php-intl php-gmp php-bcmath php-xml php-imagick php-zip 2. Mysql创建用户 这块在Next cloud的官网上有教程,可以按照自己需要去修改,不过localhost那个因为我自己不太会就没去改; # 启动MySQL客户端 root@localhost:~# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 52 Server version: 10.6.18-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. # 创建一个名为'username'的用户,该用户只能从'localhost'访问数据库,并设置密码为'password' MariaDB [(none)]> CREATE USER 'username'@'localhost' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.002 sec) # 创建一个名为'nextcloud2'的数据库,如果不存在,使用'utf8mb4'字符集和'utf8mb4_general_ci'排序规则 MariaDB [(none)]> CREATE DATABASE IF NOT EXISTS nextcloud2 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; Query OK, 1 row affected (0.002 sec) # 授予用户'username'在'nextcloud2'数据库上的所有权限 MariaDB [(none)]> GRANT ALL PRIVILEGES ON nextcloud2.* TO 'username'@'localhost'; Query OK, 0 rows affected (0.002 sec) # 刷新权限,使更改生效 MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.002 sec) # 退出MySQL MariaDB [(none)]> \q Bye 3. 获取Next cloud 可以从这里找 Index of / (nextcloud.com) 需要的版本 如果是Linux服务端可以从这里找 Index of /server/releases (nextcloud.com) # 目前我用到的版本是30.0.0 wget https://download.nextcloud.com/server/releases/nextcloud-30.0.0.zip # 可以先解压再cp到指定位置 unzip nextcloud-30.0.0.zip # 会得到一个nextcloud文件夹,就是将这个文件夹cp到/var/wwww/目录下 cp -r nextcloud /var/wwww/ # 然后将 Nextcloud 目录的所有权更改为 HTTP 用户 # 但是其实哥们好像没有执行这个操作,目前倒是没遇到什么问题 sudo chown -R www-data:www-data /var/www/nextcloud 4. 配置Apache2 4.1 安装apache2 apt update && apt install apache2 -y 4.2 开启Apache2服务 service apache2 start 这个时候应该可以在内网环境的http服务上看到apache2的默认配置界面了 root@localhost:~# ifconfig Warning: cannot open /proc/net/dev (Permission denied). Limited output. lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) rmnet_data2: flags=65<UP,RUNNING> mtu 1460 inet 这段个人ip哥们就暂时不展示了嗷 netmask 255.255.255.248 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) rndis0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.143.215 netmask 255.255.255.0 broadcast 192.168.143.255 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) # 这里这个192.168.143.215就是设备在内网的IP了,将他输入到浏览器应该就可以看到默认界面了 http://192.168.143.215 4.3 创建配置文件 到 /etc/apache2/sites-available/ 目录下,创建一个nextcloud.conf文件 cd /etc/apache2/sites-available/ vim nextcloud.conf 参考大佬的教程 ubuntu 22.04安装部署nextcloud最新版-笔记_netiii 将下列内容复制进去 <VirtualHost *:8080> # 这里我另一个机器用80端口会报错,所以就改成8080了 DocumentRoot /var/www/nextcloud/ ServerName 192.168.143.215 #修改自己的服务器IP或者域名 <Directory /var/www/nextcloud/> Require all granted AllowOverride All Options FollowSymLinks MultiViews <IfModule mod_dav.c> Dav off </IfModule> </Directory> </VirtualHost> 跟着教程走一遍,因为在termux中,和正常的Linux系统略有不同 a2ensite nextcloud.conf reload apache2 a2enmod rewrite headers env dir mime service apache2 restart # 如果有什么报错,我没管它,没看到有什么明显的影响 5. 网页配置 然后就可以访问( http://yourip :yourport)设定管理员账户和密码,配置MySQL数据库接口 这里IP就是 ifconfig 返回的那个内网地址; port就是在nextcloud.conf中配置的接口; 我的配置是 http://192.168.143.215:8080 如果完全和我的教程来,一字不改的话 MySQL用户名是 username 数据库名是 nextcloud2 数据库密钥是 password 数据库地址就是默认的 localhost ComfyUI运行Z-Image-Turbo 当然,这是在proot-distro容器环境中 1. 从GitHub拉取项目 git clone https://github.com/comfyanonymous/ComfyUI.git 2. 准备python环境 uv venv --python 3.11.9 source .venv/bin/activate ps:这里之所以用python3.11.9是因为我之前用3.12会在依赖安装那部分大量报错;这个版本是当前(2025.11)可用的最新版本了 3. 安装依赖 UV_LINK_MODE=copy uv pip install -r requirements.txt --no-cache-dir --force-reinstall 4. 添加一些插件,比如 comfy-gguf 来支持gguf格式的模型(不然可能炸) # 到custom目录下,用git clone拉取 git clone https://github.com/city96/ComfyUI-GGUF.git # cd到ComfyUI-GGUF目录下安装依赖 UV_LINK_MODE=copy uv pip install -r requirements.txt --no-cache-dir --force-reinstall uv简直是termux运行comfyui的神奇喵喵工具 UV_LINK_MODE=copy uv pip install -r requirements.txt --no-cache-dir --force-reinstall ,之前没接触过的时候用python3自带的venv,依赖完全用不了大片的error 5. 回到ComfyUI目录下,写个运行小脚本就可以部署了 touch run.sh \ chmod +x run.sh \ echo "python main.py --cpu --use-split-cross-attention --listen 0.0.0.0 --port 8888" >> run.sh \ ./run.sh ps:上边这个8888纯粹是顺手,而且没root的话,数字小于4000的端口基本用不来 IPv6 这里提一嘴IPv6,我用的是电信的流量卡,查了一下有IPv6 查询方式很多,这里写一下一种termux命令行里的方法 curl -6 ifconfig.me IPv6访问时是http://[xxxx]:port/;一定要加[ ] 实测可以远程访问网页,(导航页是让AI写的),ssh链接使用Termius也可以直连; 但是就像我白天发帖问的,Obsidian的self-hosted live sync插件不能正常使用IPv6,会报错说找不到; 在这里请教各位佬,有没有办法解决这个问题。 wireguard或者Tailsce之类的组网当然可以,不过直接用IPv6不是可以少开一个APP嘛 END 8 个帖子 - 4 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-26 21:56:01+08:00 · tech

本期主题:解决termux安装ubuntu的各种问题 前四期回顾: 【超详细】手机搭建服务器 · 第 一 期 【超详细】手机搭建服务器 · 第 二 期 【超详细】手机搭建服务器 · 第 三 期 【超详细】手机搭建服务器 · 第 四 期 [!note] 前几期完成了什么 第一期主要说的是必备条件; 第二期讲了如何解决手机供电问题; 第三期讲了如何让wifi用不断连(不过代码在第四期做了重大更新); 第四期实现了如何让ipv6一直处于可用状态和如何自动更新DDNS 这一期主要讲termux如何安装ubuntu。 原本类似的教程网络上很多,感觉没有出的必要。但是在安装的过程中,遇到了很诡异的问题,然后困扰了我很久,而且网上相关的解决方案基本没有,好不容易终于找到了一个解决方案,所以想着记录下来。 一、先准备 Termux 环境 1. 客户端选择: 大家可以安装 termux termux,也可以安装 ZeroTermux 。我自己安装的是ZerTermux。 2.更新环境 ,并且安装常用工具包 pkg update -y pkg upgrade -y pkg install -y curl wget unzip nano coreutils openssl openssl-tool termux-api 3.刷入 BusyBox模块 官方仓库: GitHub - Magisk-Modules-Repo/busybox-ndk: busybox-ndk · GitHub 下载链接: Download Busybox for Android NDK-1.36.1-13614.zip (Magisk) 4.刷入chroot-distro 模块 chroot-distro.zip (18.4 KB) 两个模块都刷入以后,记得重启手机 5.给 Termux 创建快捷的chroot-distro 命令: 在 Termux 执行: cat > $PREFIX/bin/chroot-distro <<'EOF' #!/data/data/com.termux/files/usr/bin/bash args="" for arg in "$@"; do escaped_arg=$(printf '%s' "$arg" | sed "s/'/'\\\\''/g") args="$args '$escaped_arg'" done su -c "/system/bin/chroot-distro $args" EOF chmod +x $PREFIX/bin/chroot-distro 然后测试: chroot-distro list 如果正常,说明快捷命令创建成功。 6.下载ubuntu: chroot-distro download ubuntu 看自己要安装什么版本,输入对应的数字回车即可,我选的是ubuntu 24.04。所以输入6回车。此处没有截图,因为忘记截图了。 7.安装ubuntu: chroot-distro install ubuntu 出现 ~ $ chroot-distro install ubuntu -bash: cannot set terminal process group (25325): Inappropriate ioctl for device -bash: no job control in this shell root@localhost:~# 意味着成功了。 [!warning] 到这里其实一切都很正常。也比较简单,几乎不会出什么问题。重点在下面步骤。 8.更新ubuntu内置包 在termux中执行 apt update 命令,然后会遇到报错问题。 解决apt update 办法是: 8.1 用MT管理器,把 /data/local/chroot-distro/ubuntu/etc/pam.d/su-l 这个文件中的这句话注销就不会报错了: # session optional pam_keyinit.so force revoke 。也就是在这句话前面加上#号,或者删除这句话。 8.2 继续在termux中执行下面这代码: cat > /etc/resolv.conf <<'EOF' nameserver 223.5.5.5 nameserver 119.29.29.29 nameserver 8.8.8.8 nameserver 1.1.1.1 EOF groupadd -g 3003 aid_inet groupadd -g 3004 aid_net_raw groupadd -g 1003 aid_graphics usermod -g 3003 -G 3003,3004 -a _apt usermod -G 3003 -a root 9.安装几个最基础的工具: apt install -y curl wget vim nano iproute2 procps ca-certificates 如果输入 ip addr 或者输入 ps -ef | head 都有输出,那就表示ubuntu现在基本可用了 10.创建普通用户和禁止root用户登录 为了安全,强烈建议使用拥有 sudo 权限的普通用户进行日常操作,然后禁止 root 用户直接通过 SSH 登录。在termux中的操作如下: 创建新用户: useradd -m -s /bin/bash 用户名 更改密码: passwd 用户名 安装 sudo: apt install -y sudo 加入sudo组: usermod -aG sudo server 更改密码时,控制台看不见,自己注意输入就行 测试普通用户提权是否ok: 先退出整个temux,重新进入termux,然后输入su回车 接着登录ubuntu: chroot-distro login ubuntu 然后切换到刚刚创建的普通用户 su - 用户名 进入后测试提权: sudo -i 如果能进入: root@localhost:~# 说明普通用户创建成功,并且 sudo 正常。 11.如何禁止root ssh登录: 先安装ssh: apt install -y openssh-server 直接执行这组命令: if grep -qE '^[# ]*PermitRootLogin' /etc/ssh/sshd_config; then sed -i 's/^[# ]*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_configelse echo 'PermitRootLogin no' >> /etc/ssh/sshd_configfi 然后确认: grep -n '^PermitRootLogin' /etc/ssh/sshd_config 应该看到: PermitRootLogin no 如果不放心,也可以用mt管理器,进入 /data/local/chroot-distro/ubuntu/etc/ssh/sshd_config 中查看。 [!note]结束语 还是老规矩,有什么问题欢迎大家及时反馈。看到后都会一一回复解答的 5 个帖子 - 4 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-18 05:48:37+08:00 · tech

因为本人日常需要无网络的环境下进行本地开发,由于vscode网页版交互难受,且termux没有proot容器里面的环境完整。 所有希望有个脚本能够快速安装proot并且termux:x11桌面外加开发环境 个人思路: GitHub - Xynrin/termux-setup-program: Termux 一键开发环境:Ubuntu (proot-distro) + XFCE + Termux:X11 + VSCode + Python/Node/C++ · GitHub 这是仓库地址,可以用raw在线脚本,一个termux里面运行给termux初始化,结束后echo另一个在线脚 本给容器里面用(用户手动),然后提供本地命令ubuntu快速启动proot容器ubuntu,容器也弄好以后echo下一个在线脚本,在termux中创建快速启动桌面 阶段1: Termux 中运行在线脚本 → 初始化 Termux + 安装 proot Ubuntu ↓ 结束后 echo 下一条命令 阶段2: 用户手动进入容器,运行另一个在线脚本 → 初始化容器内环境 ↓ 结束后 echo 下一条命令 阶段3: 回到 Termux,运行在线脚本 → 创建快速启动桌面命令(ubuntu/startde) 3 个帖子 - 3 位参与者 阅读完整话题