本期主题: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 位参与者