📚 Termux 无 Root 学习开发系列
阶段一:环境搭建与终端基础 ✅ 已完成
01-05 Termux 安装 → 包管理 → 文件管理 → Vim/tmux
阶段二:编程开发环境 ✅ 已完成
06-09 Python → C/C++ → Node.js → Git
阶段三:网络与远程操作 ✅ 已完成
10-12 SSH → 网络工具 → 网络代理
阶段四:Termux:API 与自动化
✓ 13 Termux:API 硬件调用
14 定时任务与自动化(当前篇)
阶段五至九共 14 篇,后续持续更新

14 定时任务与自动化:让脚本自己跑起来

难度:进阶 | 前置:13 Termux:API 硬件调用
读完本篇你将能:用 cron 和 termux-job-scheduler 定时执行脚本、在手机桌面添加一键快捷方式、配置开机自动启动服务、编写带日志和错误处理的可靠自动化脚本——把手机变成一台无人值守的自动化终端。
📑 本文目录
01cron 定时任务:经典 Linux 调度器
02termux-job-scheduler:Android 原生调度
03Termux:Widget:桌面一键快捷方式
04Tasker 联动:事件驱动自动化
05开机自启:Termux:Boot
06日志记录与错误处理

01 cron 定时任务:经典 Linux 调度器

上一篇你已经掌握了 Termux:API 的硬件调用能力——拍照、定位、传感器读取。但每次都要手动敲命令,效率太低。想象一下:如果你能让手机每天早上 7 点自动获取天气预报并推送通知,或者每小时检查一次服务器状态——这就是定时任务的用武之地。

cron 是 Linux 世界最经典的定时任务调度器,几乎所有服务器都在用它。Termux 通过 cronie 包提供了完整的 cron 实现,配合 termux-services 服务管理框架,可以像在桌面 Linux 上一样管理定时任务。

1.1 安装 cronie 与 termux-services

cronie 当前稳定版本是 1.7.2,这是一个成熟维护的项目,完全兼容传统 ISC cron 的 crontab 语法。termux-services 是 Termux 的服务管理框架,底层已切换到 runit 实现,提供 sv-enable、sv up、sv down 等命令来管理后台服务。

Bash
1
2
3
4
5
6
7
8
# 安装 cronie 和 termux-services
pkg install cronie termux-services
# 安装后必须重启 Termux 让 runit 初始化
# 完全关闭 Termux 后重新打开
# 或者手动加载服务脚本
source $PREFIX/etc/profile.d/start-services.sh

安装完成后,sv 命令就可用了。先启动 crond 服务:

Bash
1
2
3
4
5
6
7
8
9
10
11
# 查看可用的服务
ls $PREFIX/etc/sv/
# 启动 crond 服务(一次性的)
sv up crond
# 永久启用 crond(每次 Termux 启动自动运行)
sv-enable crond
# 检查服务状态
sv status crond

执行 sv status crond 后,如果看到 run: crond: ... 字样,说明 cron 守护进程已正常运行。如果遇到问题,可以查看服务日志:cat $PREFIX/var/log/sv/crond/current。

1.2 crontab 语法与配置

crontab 是 cron 的任务表,每行定义一个定时任务。格式为五个时间字段加一个命令:

crontab 格式
# 分 时 日 月 周 命令
*/5 * * * * echo "每5分钟执行"
0 7 * * * echo "每天7点执行"
0 */2 * * * echo "每2小时执行"
30 9 * * 1-5 echo "工作日9:30执行"

用 crontab -e 编辑你的定时任务。下面是一个实际例子——每天 8 点获取电池状态并写入日志:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 编辑 crontab
crontab -e
# 在打开的编辑器中添加以下内容:
# 每天 8:00 记录电池状态到日志文件
0 8 * * * termux-battery-status | jq '.percentage' >> /data/data/com.termux/files/home/battery.log
# 每 30 分钟检查服务器是否在线
*/30 * * * * ping -c 1 8.137.176.208 >/dev/null 2>&1 || termux-notification --title "Server Down"
# 查看已配置的定时任务
crontab -l
# 删除所有定时任务
crontab -r
⚠️ 常见错误
*/5 * * * * python script.py — cron 环境的 PATH 与交互式 Shell 不同,python 可能找不到
✓ 正确:在 crontab 中使用绝对路径:*/5 * * * * /data/data/com.termux/files/usr/bin/python /data/data/com.termux/files/home/script.py
💡 小贴士
cron 在 Termux 中有一个重要限制:当 Android 系统杀掉 Termux 后台进程时,crond 也会被终止,所有定时任务停止运行。解决方法是在电池设置中将 Termux 设为"不受限制",并在脚本中调用 termux-wake-lock 保持 CPU 唤醒。但 wake-lock 会持续耗电,仅在需要时开启。

02 termux-job-scheduler:Android 原生调度

cron 虽然经典,但在 Android 上有一个先天缺陷——它不理解 Android 的电源管理机制。当手机进入 Doze 模式(深度休眠)时,cron 的定时任务可能被系统延迟甚至跳过。termux-job-scheduler 直接调用 Android 原生的 JobScheduler API,系统能在合适时机唤醒手机执行任务,更加省电且可靠。

termux-job-scheduler 是 termux-api 包的一部分(v0.59.0),安装 termux-api 后即可使用。它的核心优势在于可以设置执行条件:仅在 WiFi 连接时、仅在电量充足时、仅在设备空闲时触发。

2.1 基本用法

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 每小时执行一次脚本(3600000 毫秒 = 1 小时)
termux-job-scheduler --job-id 1 --period-ms 3600000 --command "echo hello >> ~/job.log"
# 每 15 分钟检查电池,仅在非低电量时执行
termux-job-scheduler --job-id 2 --period-ms 900000 --battery-not-low true --command "termux-battery-status | jq '.percentage' >> ~/battery.log"
# 仅在 WiFi 下每小时备份文件
termux-job-scheduler --job-id 3 --period-ms 3600000 --network unmetered --persisted true --command "rsync -av ~/storage/shared/photos/ user@server:/backup/"
# 查看所有已调度的任务
termux-job-scheduler --pending
# 取消指定任务
termux-job-scheduler --cancel 2
# 取消所有任务
termux-job-scheduler --cancel-all

--job-id 是任务的唯一标识,相同 ID 会覆盖之前的任务。--persisted true 表示重启手机后任务依然保留。--network unmetered 表示仅在 WiFi(非计费网络)下触发。

特性 cron (cronie) termux-job-scheduler
调度精度 分钟级,精确可控 周期级,系统优化执行时机
电源管理 不感知 Doze 模式 原生 JobScheduler,休眠可唤醒
条件触发 仅时间条件 电量/网络/充电状态
重启持久化 需 sv-enable crond --persisted true 自动恢复
语法复杂度 crontab 五段式,灵活 命令行参数,简单直观

选择建议:需要精确时间控制(如每天 7:00 执行)用 cron;需要省电和条件触发(如仅在 WiFi 下备份)用 termux-job-scheduler。两者可以共存——cron 负责精确调度,JobScheduler 负责条件触发。

03 Termux:Widget:桌面一键快捷方式

定时任务解决了"自动执行"的问题,但有时候你只是想快速手动触发一个脚本——不想打开 Termux、不想敲一长串命令。Termux:Widget 就是为此而生:它在手机桌面创建快捷方式,点击即可执行预设脚本。

Termux:Widget 当前版本 v0.15.0(2025 年 9 月发布),从 F-Droid 安装。它的原理很简单:读取 ~/.shortcuts/ 目录下的脚本文件,在桌面 Widget 中列出,点击即执行。

3.1 创建桌面快捷方式

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 创建快捷方式目录
mkdir -p ~/.shortcuts
# 创建一键拍照脚本
cat > ~/.shortcuts/快速拍照 <<'EOF'
#!/data/data/com.termux/files/usr/bin/bash
TS=$(date +%Y%m%d_%H%M%S)
termux-camera-photo -c 0 ~/storage/shared/DCIM/Camera/quick_$TS.jpg
termux-notification --title "拍照完成" --content "已保存 quick_$TS.jpg"
EOF
# 创建一键获取IP脚本
cat > ~/.shortcuts/查看IP地址 <<'EOF'
#!/data/data/com.termux/files/usr/bin/bash
IP=$(curl -s ifconfig.me)
termux-notification --title "当前公网IP" --content "$IP"
termux-clipboard-set "$IP"
EOF
# 赋予执行权限
chmod +x ~/.shortcuts/*

创建脚本后,在手机桌面上长按空白处 → 添加 Widget → 找到 Termux:Widget → 拖到桌面。Widget 会列出 ~/.shortcuts/ 下所有脚本,点击即可执行。文件名就是快捷方式显示的名称。

如果需要给快捷方式分组,可以在 ~/.shortcuts/ 下创建子目录,Termux:Widget 会在 Widget 中显示为可展开的分组。例如 ~/.shortcuts/网络工具/ 和 ~/.shortcuts/日常工具/。

💡 小贴士
脚本文件的 shebang 行必须使用 Termux 完整路径 #!/data/data/com.termux/files/usr/bin/bash,不能写成 #!/bin/bash。因为 Widget 执行脚本时不会加载 Termux 的完整 PATH 环境,错误的 shebang 会导致"command not found"错误。脚本中所有命令也建议使用绝对路径。

04 Tasker 联动:事件驱动自动化

cron 和 JobScheduler 都是"时间驱动"的定时调度——到了某个时间点才执行。但现实中很多自动化需求是"事件驱动"的:收到特定短信时执行脚本、连接到家里 WiFi 时自动备份、电量低于 20% 时发送通知。这些场景需要 Tasker 出场。

Tasker 是 Android 平台最强大的自动化 App(付费应用),配合 Termux:Tasker 插件,可以在任意事件触发时执行 Termux 脚本。Termux:Tasker 插件通过 Termux:API App 的 Tasker 扩展接口工作,在 Tasker 中作为"插件操作"出现。

4.1 典型联动场景

📍 地理围栏触发

到达公司 → 执行 Termux 脚本打卡记录;离开家 → 自动发送消息给家人

📱 短信事件触发

收到含"备份"关键词的短信 → 执行 rsync 备份脚本并回复完成通知

🔋 电量状态触发

电量低于 15% → 自动 SSH 到服务器执行安全关机;充电完成 → 推送通知

🌐 WiFi 连接触发

连接家庭 WiFi → 自动同步手机照片到 NAS;断开 → 启动 SSH 隧道

4.2 配置步骤

以"收到含'备份'关键词的短信时自动执行备份脚本"为例:

1 在 Tasker 中创建 Profile → 选择 Event → Phone → Received Text,设置 Type 为 SMS,Sender 填写允许触发的号码
2 在 Task 条件中添加 Text Matches,填入 备份 关键词
3 添加 Task → 选择 Action → Plugin → Termux:Tasker → 配置中填写要执行的脚本路径
4 在 Termux 中创建对应脚本,例如 ~/tasker_backup.sh
5 测试:用另一台手机发送短信"备份"到本机,观察 Tasker 日志确认触发

Tasker 联动的优势在于事件类型极其丰富——传感器、位置、时间、通知、App 启动、屏幕状态等几十种触发条件,远超 cron 的纯时间调度。配合 Termux 的命令行能力,几乎可以实现任何自动化逻辑。

05 开机自启:Termux:Boot

前面讲了定时和事件触发,但还有一个基础场景:手机重启后,Termux 中的所有服务(sshd、crond)都停了,需要手动打开 Termux 才能恢复。Termux:Boot 解决了这个问题——手机开机时自动启动 Termux 并执行预设脚本。

Termux:Boot 最新版本 v0.8.1,从 F-Droid 安装。安装后必须手动打开一次 Termux:Boot App,它会注册 Android 的 BOOT_COMPLETED 广播接收器。之后每次手机开机,Termux:Boot 会自动启动 Termux 并执行 ~/.termux/boot/ 目录下的所有脚本(按文件名排序依次执行)。

5.1 配置开机自启脚本

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 创建 boot 目录
mkdir -p ~/.termux/boot
# 创建启动脚本(文件名前缀控制执行顺序)
cat > ~/.termux/boot/01-startup.sh <<'EOF'
#!/data/data/com.termux/files/usr/bin/bash
# 保持 CPU 唤醒,防止后台被杀
termux-wake-lock
# 启动 SSH 服务
sv up sshd
# 启动 cron 服务
sv up crond
# 记录启动日志
echo "Boot at $(date)" >> ~/boot.log
EOF
cat > ~/.termux/boot/02-notify.sh <<'EOF'
#!/data/data/com.termux/files/usr/bin/bash
# 延迟 10 秒后发送通知(等待网络就绪)
sleep 10
termux-notification --title "Termux 已启动" --content "所有服务已就绪"
EOF
# 赋予执行权限
chmod +x ~/.termux/boot/*

脚本按文件名排序依次执行,所以用数字前缀(01、02...)控制执行顺序。01-startup.sh 先获取 wake-lock 并启动核心服务,02-notify.sh 延迟后发送通知。延迟是因为开机后网络可能还没就绪,直接发通知可能失败。

⚠️ 常见错误
#!/bin/bash — Termux 没有标准的 /bin/bash 路径,开机脚本会直接报错退出
✓ 正确:使用 Termux 完整路径 #!/data/data/com.termux/files/usr/bin/bash。另一个常见问题是忘记安装后手动打开 Termux:Boot App——只有打开过一次,系统才会注册它的开机广播权限。

06 日志记录与错误处理

定时任务和开机脚本一旦脱离人工干预运行,日志和错误处理就变得至关重要。没有日志,你根本不知道昨晚 3 点的备份是否成功;没有错误处理,脚本会在某个意外条件下静默失败,直到你需要数据时才发现问题。

6.1 日志记录最佳实践

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/data/data/com.termux/files/usr/bin/bash
# reliable_backup.sh — 可靠的自动备份脚本
LOGFILE=~/logs/backup_$(date +%Y%m%d).log
BACKUP_DIR=~/storage/shared/Documents
REMOTE="user@8.137.176.208:/backup/mobile/"
# 创建日志目录
mkdir -p ~/logs
# 日志函数:带时间戳输出
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$LOGFILE"
}
# 错误处理函数:记录错误并发送通知
handle_error() {
log "ERROR: $1"
termux-notification --title "备份失败" --content "$1"
exit 1
}
# 开始执行
log "开始备份 $BACKUP_DIR"
# 检查备份目录是否存在
if [ ! -d "$BACKUP_DIR" ]; then
handle_error "备份目录不存在: $BACKUP_DIR"
fi
# 执行 rsync 备份
rsync -av "$BACKUP_DIR/" "$REMOTE" 2>&1 | tee -a "$LOGFILE"
# 检查 rsync 是否成功
if [ $? -eq 0 ]; then
log "备份成功完成"
termux-notification --title "备份成功" --content "已同步 $(date)"
else
handle_error "rsync 退出码: $?"
fi
# 清理 7 天前的日志
find ~/logs -name "backup_*.log" -mtime +7 -delete

这个脚本体现了自动化日志的几个核心原则:

• 时间戳日志:每条日志带日期时间,方便追溯。日志按天分文件(backup_YYYYMMDD.log),避免单个文件无限增长
• 错误通知:失败时不仅记日志,还通过 termux-notification 推送手机通知,让你第一时间感知
• 前置检查:执行前检查目录是否存在,避免在错误条件下继续运行
• 退出码检查:rsync 执行后检查 $? 退出码,非零即视为失败
• 日志清理:find -mtime +7 自动删除 7 天前的旧日志,防止存储膨胀

6.2 set -e 与错误陷阱

对于更复杂的脚本,可以使用 set -e 让脚本遇到任何命令失败时立即停止,配合 trap 捕获退出信号做清理工作:

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/data/data/com.termux/files/usr/bin/bash
set -e  # 任何命令失败立即退出
trap 'echo "脚本异常退出 at line $LINENO" >> ~/error.log' ERR
TMPFILE=$(mktemp)
# 清理函数:无论成功失败都执行
cleanup() {
rm -f "$TMPFILE"
termux-wake-unlock
}
trap cleanup EXIT
# 获取 wake-lock 防止休眠
termux-wake-lock
# 主逻辑...任何命令失败都会触发 trap
curl -s https://api.example.com/data | jq '.' > "$TMPFILE"

set -e 让脚本在命令失败时立即停止,避免错误级联。trap ... ERR 在错误发生时记录退出行号。trap cleanup EXIT 在脚本退出时(无论成功还是失败)清理临时文件并释放 wake-lock。这三层防护确保脚本在各种异常情况下都不会留下垃圾或导致资源泄漏。

💡 小贴士
自动化脚本的三个层次:第一层是"能跑"——命令正确,逻辑通顺;第二层是"能查"——有日志,失败了能找到原因;第三层是"能恢复"——有错误处理,临时文件清理,资源释放。从第一层到第三层,是脚本从"玩具"变成"工具"的过程。本篇所有示例都达到了第三层标准。
📖 知识回顾
cronie + termux-services sv-enable / sv up crontab 五段式语法 termux-job-scheduler Termux:Widget 桌面快捷方式 Tasker 事件驱动 Termux:Boot 开机自启 set -e + trap 错误处理 日志轮转与清理
✏️ 动手练习
🟢 基础验证
安装 cronie 和 termux-services,启动 crond 服务,配置一个 crontab 任务:每 5 分钟在 ~/ping.log 中记录当前时间戳(提示:date >> ~/ping.log)。等待 10 分钟后检查日志文件,确认任务正常运行。
🟡 组合应用
创建一个 Termux:Widget 快捷方式脚本:点击后获取当前 GPS 定位(termux-location),用 curl 调用免费天气 API(如 wttr.in)查询当地天气,将结果通过 termux-notification 推送通知。要求脚本包含错误处理——GPS 获取失败时推送"定位失败"通知。
🔴 开放挑战
设计一个完整的"手机服务器看门狗"系统:使用 termux-job-scheduler 每 30 分钟 ping 你的服务器,如果连续 3 次失败则推送紧急通知。要求:(1) 用文件记录连续失败次数 (2) 恢复在线时推送"服务恢复"通知 (3) 日志按天分文件并自动清理 7 天前的记录。提示:可以结合本篇的日志函数和错误处理模式。
下篇预告
15 proot-distro:在手机上运行完整 Linux 发行版
将进入阶段五,学习用 proot-distro 在 Termux 中安装 Ubuntu、Debian、Arch 等完整 Linux 系统,突破 Termux 包管理的限制
关注公众号获取更多内容