SMF 2.1.8 常用 CLI 命令与工具详解

SMF 2.1.8 命令行操作面:cron.php 计划/后台任务引擎(停用锁、到期执行、审计实测)、update_timezones 等维护脚本、SSI.php 集成 API、数据库备份恢复与文件层运维命令。

SMFSMF论坛PHPMySQLDocker自托管2026/11/02

SMF 2.1.8 常用 CLI 命令与工具详解

目标:SMF 是 PHP Web 应用,官方不提供独立的管理 CLI 二进制,其命令行操作面分布在「内置脚本 cron.php + other/ 维护脚本 + SSI.php 集成 API + 数据库客户端」四处。本文把这四类工具与对应运维操作逐项实测展开,全部命令与回显来自 Ubuntu 24.04.5 LTS(x86_64)+ PHP 8.2.35 + MariaDB 11.4.13 的 SMF 2.1.8 实例(2026-11-02)。

一、环境信息

  • 操作系统:Ubuntu 24.04.5 LTS(x86_64)
  • 软件版本:SMF 2.1.8(官方最新稳定版,GitHub tag v2.1.8,2026-10-11 发布,2026-11-02 查询)
  • 运行环境:PHP 8.2.35(Apache 模块形态)+ MariaDB 11.4.13
  • 论坛目录:/var/www/html(Apache 站点根,Settings.php 位于其中)
  • 数据库:库名 smf,账号 smf,密码 q1w2e3r4,表前缀 smf_,共 73 张表
  • 演示账号:管理员 admin,密码 q1w2e3r4
  • 访问地址:http://192.168.1.172:8138
  • 部署方式:按本专栏部署篇完成(安装向导五步 + 安装脚本删除,论坛已处于可运行状态)

二、工具概览

SMF 2.1.8 实例上可脚本化调用的全部入口(目录清单实测):

入口位置用途调用方式
cron.php/var/www/html/cron.php计划任务 + 后台任务执行引擎(2.1 线取代 2.0 的 fetch.php)php -q + crontab
update_timezones.php/var/www/html/other/校验/维护内置时区数据php -q
db_last_error.phpother/(0 字节模板)+ cache/(运行时)数据库错误限流记录cat 查看
update_unicode_data.php、update_version_numbers.php/var/www/html/other/官方发布流程开发者脚本日常运维不使用
SSI.php/var/www/html/SSI.php程序化读取论坛数据(40 个 ssi_* 函数)PHP require
mariadb / mariadb-dump数据库服务器配置读写、备份恢复、日志查询客户端命令
Settings.php/var/www/html/维护模式、缓存、连接等文件层开关sed/grep
install.php / upgrade.phpother/(安装完成后从站点根删除)安装/升级向导浏览器执行,CLI 做前后置

⚠️ 篇型适配说明:D1 篇型面向「有 CLI 的组件」。SMF 的管理主面是 Web 后台 + 数据库,官方 CLI 仅 cron.php 一个常驻入口加 other/ 下两三个维护脚本,没有 smf-cli 这类管理命令。本文按实际形态组织:第四章展开 cron.php,第五、六章展开维护脚本与集成 API,第七、八章把后台运维职能(改配置、备份、清缓存、开维护模式)落到可执行的 SQL 与文件层命令上,不虚构不存在的命令。

三、前置条件

  1. PHP CLI 可用(实测):
php -v
PHP 8.2.35 (cli) (built: Oct 28 2026 01:29:54) (NTS)
  1. 数据库客户端可用,且能从 Web 主机连通数据库:
mariadb -usmf -pq1w2e3r4 smf -e "SELECT VERSION();"
VERSION()
11.4.13-MariaDB-ubu2404
  1. 论坛已完成安装(Settings.php 存在且可读);
  2. cron.php 以 Web 进程账号 www-data(实测 UID 33)或 root 运行——需能读 Settings.php 并写 cache/;
  3. 版本确认(后续所有回显基于该版本):
mariadb -usmf -pq1w2e3r4 smf -e "SELECT value AS smf_version FROM smf_settings WHERE variable='smfVersion';"
smf_version
2.1.8

四、cron.php:计划任务与后台任务引擎

4.1 机制与源码常量

cron.php 是 SMF 唯一的官方 CLI 常驻入口。它消费两张队列:smf_background_tasks(发帖通知、附件处理等即时后台任务)与 smf_scheduled_tasks(每日/每周计划任务)。源码关键常量(/var/www/html/cron.php 实测):

define('MAX_CRON_TIME', 10);        // 单轮后台任务时间预算(秒)
define('MAX_CLAIM_THRESHOLD', 300); // 已认领任务超 300s 未完结可被重新认领

执行顺序:先循环取后台任务(限时 10 秒);若耗时未过半,再检查 next_task_time,到期则调用 AutoTask()——一次只执行一个到期的计划任务(源码查询条件为 WHERE disabled = 0 AND next_time <= 当前时间 ORDER BY next_time ASC LIMIT 1,实测见 4.5),把它推到下一周期后写回 next_task_time。

💡 技术拓展:SMF 2.0 线的对应入口是 fetch.php(仅能被网页 img 请求触发);2.1 统一为 cron.php 并支持 CLI 直跑(本文实测 exit=0)。若从 2.0 升级,crontab 里的 fetch.php 路径需改为 cron.php。

4.2 手动执行

cd /var/www/html && php -q cron.php; echo "exit=$?"

实测回显:

exit=0

静默无输出即正常。-q 抑制 CLI 的 HTML 注释头,日志更干净。

4.3 配置系统 crontab

SMF 默认依赖「网页访问触发」:页面在任务到期时嵌入对 cron.php?ts=<时间戳> 的请求(源码校验 ts 必须是 15 的倍数且距今 ≤20 秒,实测),没有访客就没有任务执行。生产环境务必配置服务器端 cron,新建 /etc/cron.d/smf:

* * * * * www-data php -q /var/www/html/cron.php > /dev/null 2>&1

要点:

  • 频率不得低于单轮预算 MAX_CRON_TIME=10 秒,标准写法即每分钟一次;
  • 运行账号要能读 Settings.php、写 cache/(本文实例为 www-data);
  • 配置后以 smf_log_scheduled_tasks 出现新执行行验证(4.7),而非看 cron 日志。

4.4 内置计划任务清单(实测 11 项)

mariadb -usmf -pq1w2e3r4 smf -e \
  "SELECT id_task,task,time_regularity,time_unit,disabled,next_time FROM smf_scheduled_tasks ORDER BY id_task;"

实测回显:

id_task	task	time_regularity	time_unit	disabled	next_time
3	daily_maintenance	1	d	0	1793664060
5	daily_digest	1	d	0	1793664000
6	weekly_digest	1	w	0	1794182400
7	fetchSMfiles	1	d	0	1793723400
8	birthdayemails	1	d	1	0
9	weekly_maintenance	1	w	0	1794182400
10	paid_subscriptions	1	d	1	0
11	remove_temp_attachments	1	d	0	1793664120
12	remove_topic_redirect	1	d	0	1793664180
13	remove_old_drafts	1	d	0	1793664240
14	prune_log_topics	1	w	1	0

逐项含义与默认状态:

task用途默认
daily_maintenance每日维护:清理过期日志/封禁、统计与缓存维护启用
daily_digest / weekly_digest每日/每周邮件摘要(成员订阅制,无人订阅则空转)启用
fetchSMfiles拉取官方文件(版本信息、公告),需外联 simplemachines.org启用
birthdayemails生日邮件停用
weekly_maintenance每周深度维护(表优化、数据清理)启用
paid_subscriptions付费订阅结算停用
remove_temp_attachments清理未绑定的临时附件启用
remove_topic_redirect清理主题移动产生的跳转记录启用
remove_old_drafts清理过期草稿启用
prune_log_topics修剪主题浏览记录表停用

disabled=1 的三项在后台「维护 → 计划任务」页可开关;time_regularity + time_unit(d/w)定义周期,next_time 为下次执行的 Unix 秒。

4.5 强制到期任务执行(实测)

场景:升级后想立即跑一次清理任务,不等周期。把 remove_temp_attachments 置为到期:

mariadb -usmf -pq1w2e3r4 smf -e \
  "UPDATE smf_settings SET value='1' WHERE variable='next_task_time';
   UPDATE smf_scheduled_tasks SET next_time=1 WHERE task='remove_temp_attachments';
   SELECT value AS next_task_time FROM smf_settings WHERE variable='next_task_time';
   SELECT task,next_time FROM smf_scheduled_tasks WHERE task='remove_temp_attachments';"
next_task_time
1
task	next_time
remove_temp_attachments	1

执行一轮 cron:

php -q /var/www/html/cron.php; echo "exit=$?"
exit=0

验证任务已被执行并推入下一周期:

mariadb -usmf -pq1w2e3r4 smf -e \
  "SELECT value AS next_task_time_after FROM smf_settings WHERE variable='next_task_time';
   SELECT task,next_time FROM smf_scheduled_tasks WHERE task='remove_temp_attachments';
   SELECT COUNT(*) AS log_rows FROM smf_log_scheduled_tasks;"

实测回显:

next_task_time_after
1793664000
task	next_time
remove_temp_attachments	1793664120
log_rows
10

解读:next_time 从 1 跳到 1793664120(次日 00:02 的对齐周期位);next_task_time 指向下一个到期任务(daily_digest 的 00:00);smf_log_scheduled_tasks 新增执行记录。一次 cron 只推进一个到期计划任务——若积压多个,多跑几轮即可。

4.6 cron.lock 停用开关(实测)

源码行为:cron.php 启动即检查 cache/cron.lock,存在则立刻静默退出(file_exists($cachedir . '/cron.lock') → obExit_cron())。用于升级/批量维护期间暂停一切任务:

touch /var/www/html/cache/cron.lock
php -q /var/www/html/cron.php; echo "exit=$?"

实测:锁存在时即使任务已到期(next_task_time=1),执行后 next_task_time 仍为 1,任务纹丝不动:

next_task_time_with_lock
1
rm /var/www/html/cache/cron.lock
php -q /var/www/html/cron.php; echo "exit=$?"

去锁后重跑,任务立即按 4.5 正常推进(exit=0)。

⚠️ 注意:cron.lock 是静默失效——exit=0 不报错,极易在升级后被遗忘,导致论坛任务停摆数周。升级收尾清单里必须包含 rm /var/www/html/cache/cron.lock。

4.7 执行审计与后台队列

任务执行历史(判断「任务到底跑没跑」的唯一可靠依据):

mariadb -usmf -pq1w2e3r4 smf -e \
  "SELECT id_task, FROM_UNIXTIME(time_run) ran, time_taken FROM smf_log_scheduled_tasks ORDER BY time_run DESC LIMIT 10;"

实测回显(节选):

id_task	ran	time_taken
13	2026-11-02 09:32:00	0
11	2026-11-02 09:31:38	0
12	2026-11-02 09:31:38	0
9	2026-11-02 09:31:26	0
7	2026-11-02 09:31:12	17
6	2026-11-02 09:27:30	0
3	2026-11-02 09:25:24	0
5	2026-11-02 09:25:24	0

id_task=7(fetchSMfiles)耗时 17 秒——它要外联官方站点,是 11 项中唯一明显慢的任务;其余均为秒级。

后台任务队列水位:

mariadb -usmf -pq1w2e3r4 smf -e "SELECT COUNT(*) AS background_tasks FROM smf_background_tasks;"
background_tasks
0

持续非零说明任务消费不动(cron 频率不足或报错),查 smf_log_errors。后台任务的具体实现是 $sourcedir/tasks/ 下的类文件(实测 19 个):CreatePost-Notify.php、Register-Notify.php、Likes-Notify.php 等通知类,加 ExportProfileData.php(数据导出)、UpdateTldRegex.php、UpdateUnicode.php(数据更新)。

五、other/ 维护与升级脚本

5.1 update_timezones.php:时区数据维护

用途:把 SMF 内置时区数据(Sources/Subs-Timezones.php、语言包 Timezones.english.php)与 IANA tzdb/CLDR 比对,报告变更条目。PHP/系统 tzdata 升级后(如时区改名、夏令时规则变化)用它核查:

cd /var/www/html && php -q other/update_timezones.php; echo "exit=$?"

实测回显:

The following time zones changed in unexpected ways. Please review them manually to figure out what to do.
	Europe/Kyiv

Done. No changes were made.
exit=0

解读:脚本列出与内置数据不一致的时区(本例 Europe/Kyiv,即基辅时区改名事件),但不自动改写内置文件(Done. No changes were made.),需人工确认后处理。

⚠️ 注意:该脚本从 api.github.com 与 raw.githubusercontent.com 抓取 tzdb 标签与 CLDR 数据(源码常量 TZDB_TAGS_URL、TZDB_FILE_URL、CLDR_TZNAMES_URL,实测)。受限网络下每次抓取都要等满 socket 超时,本文实测全程耗时超过 2 分钟才降级完成。请在可直连外网或已配代理的主机上运行。

5.2 数据库错误限流:cache/db_last_error.php

SMF 连不上数据库时,把最近一次错误时间戳写入 cache/db_last_error.php,用于限流错误邮件(配合文件层 $db_error_send 开关)。查看:

cat /var/www/html/cache/db_last_error.php

实测回显:

<?php
$db_last_error = 0;
?>

0 表示近期无数据库错误记录。发布包 other/db_last_error.php 是 0 字节占位模板(实测 ls -l),运行时真正生效的是 cache/ 下这份。

5.3 开发者脚本(了解即可)

other/ 目录实测还含 update_unicode_data.php(重新生成 Unicode 数据表)与 update_version_numbers.php(维护版本号数组)——服务于官方发布流程,日常运维不使用。同目录的 install.php、upgrade.php 与 install_2-1_mysql.sql、upgrade_2-1_mysql.sql 等是安装/升级向导本体,站点根目录的副本在安装完成后必须删除(本专栏部署篇 4.8 节实测:不删则后台持续显示 MAJOR SECURITY RISK 告警)。

5.4 升级与维护流程

SMF 升级本体走浏览器向导(upgrade.php,179 KB,实测文件大小),CLI 负责前后置四步,串起本文各节命令:

# 1. 备份(命令实测见 7.4/7.5)
mariadb-dump -usmf -pq1w2e3r4 smf > /tmp/smf_backup.sql

# 2. 暂停任务 + 进维护模式(实测见 4.6/8.1)
touch /var/www/html/cache/cron.lock
sed -i 's/^\$maintenance = 0;/\$maintenance = 1;/' /var/www/html/Settings.php

# 3. 替换程序文件(保留 Settings.php 与 attachments/、avatars/、cache/ 目录),
#    浏览器访问 https://<站点>/upgrade.php 按向导走完数据库结构升级

# 4. 收尾:恢复任务与访问,删除向导脚本
rm /var/www/html/cache/cron.lock
sed -i 's/^\$maintenance = 1;/\$maintenance = 0;/' /var/www/html/Settings.php
rm -f /var/www/html/install.php /var/www/html/upgrade.php

验证升级结果:SELECT value FROM smf_settings WHERE variable='smfVersion'; 返回新版本号;php -q /var/www/html/cron.php 恢复消费任务。

六、SSI.php:程序化集成 API

6.1 定位

SSI(Server Side Include):任何 PHP 脚本 require 论坛根目录的 SSI.php 后,即可调用 40 个 ssi_* 函数读取论坛数据(最新主题、统计、在线人数等),用于把论坛内容嵌入已有页面或写运维脚本。官方给出完整示例页 ssi_examples.php(站点根目录,实测存在)。

6.2 CLI 实测示例

php -r 'require("/var/www/html/SSI.php"); ssi_recentTopics();'

输出节选(实测首尾,HTML 表格):

		<table style="border: none" class="ssi_table">
			<tr>
				<td style="text-align: right; vertical-align: top; white-space: nowrap">
					[<a href="http://127.0.0.1:8138/index.php?board=1.0">General Discussion</a>]
				</td>
				<td style="vertical-align: top">
					<a href="http://127.0.0.1:8138/index.php?topic=2.msg2;topicseen#new">SMF 2.1.8 部署验证帖</a>
					by <a href="http://127.0.0.1:8138/index.php?action=profile;u=1">admin</a>
					<a href="http://127.0.0.1:8138/index.php?topic=1.msg1;topicseen#new">Welcome to SMF!</a>
					by Simple Machines

解读:函数直接连库读取并输出渲染好的 HTML(含站内链接),本文部署验证时发的帖子如实出现在结果里。SSI 复用 Settings.php 的数据库连接,CLI 下无需任何额外参数。

6.3 ssi_* 函数速查(实测 40 个)

grep -c '^function ssi_' /var/www/html/SSI.php
40

按用途分组(函数名实测自源码):

组函数
内容输出ssi_recentTopics、ssi_recentPosts、ssi_fetchPosts、ssi_queryPosts、ssi_boardNews、ssi_news、ssi_recentAttachments、ssi_topTopics、ssi_topTopicsReplies、ssi_topTopicsViews、ssi_topPoster、ssi_topBoards、ssi_topPoll、ssi_recentPoll、ssi_showPoll、ssi_pollVote
会员ssi_latestMember、ssi_randomMember、ssi_fetchMember、ssi_fetchGroupMembers、ssi_queryMembers、ssi_welcome、ssi_login、ssi_logout、ssi_checkPassword
日历事件ssi_todaysBirthdays、ssi_todaysHolidays、ssi_todaysEvents、ssi_todaysCalendar、ssi_recentEvents
站点框架/统计ssi_full、ssi_menubar、ssi_boardStats、ssi_whosOnline、ssi_logOnline、ssi_version、ssi_software、ssi_copyright、ssi_quickSearch、ssi_shutdown

逐个函数的参数与效果以 ssi_examples.php 示例页为准(浏览器打开即见实测渲染)。

6.4 SSI 专用数据库账号

文件层预留 $ssi_db_user / $ssi_db_passwd(实测本实例为空 = 未启用,SSI 回落到主账号 smf)。对外页嵌入论坛数据时建议建只读账号最小授权,并在 Settings.php 填入该账号:

GRANT SELECT ON smf.* TO 'ssi_ro'@'localhost' IDENTIFIED BY 'q1w2e3r4';
FLUSH PRIVILEGES;

💡 说明:SSI 账号机制是 SMF 内置的降级连接——主账号连接失败时 Load.php 改用 $ssi_db_*(源码注释实测),因此只读账号同时兼任「嵌入场景最小权限」与「故障降级」两个角色。

七、数据库 CLI:配置、备份与恢复

7.1 连接与配置读写

数据库层配置全在 smf_settings 表(键值对,两层配置模型详见《SMF 2.1.8 配置参数详解》)。读:

mariadb -usmf -pq1w2e3r4 smf -e \
  "SELECT variable,value FROM smf_settings WHERE variable IN
   ('allow_guestAccess','attachmentEnable','enableErrorLogging','time_format') ORDER BY variable;"

实测回显:

variable	value
allow_guestAccess	1
attachmentEnable	1
enableErrorLogging	1
time_format	%b %d, %Y, %I:%M %p

写(脚本化改配置):

mariadb -usmf -pq1w2e3r4 smf -e \
  "UPDATE smf_settings SET value='0' WHERE variable='allow_guestAccess';"

⚠️ 注意:SQL 直改不触发清缓存,改完执行 8.2 删缓存文件,否则页面仍读旧值。

7.2 常用运维查询(实测)

mariadb -usmf -pq1w2e3r4 smf -e \
  "SELECT COUNT(*) AS tables_total FROM information_schema.tables WHERE table_schema='smf';
   SELECT COUNT(*) AS topics FROM smf_topics;
   SELECT COUNT(*) AS posts FROM smf_messages;
   SELECT COUNT(*) AS members FROM smf_members;
   SELECT COUNT(*) AS log_errors FROM smf_log_errors;
   SELECT COUNT(*) AS admin_actions FROM smf_log_actions;"
tables_total
73
topics
2
posts
2
members
1
log_errors
0
admin_actions
2

解读:log_errors=0 即论坛当前无未处理 PHP/数据库错误;log_actions 是后台操作审计(本文部署验证产生的 2 条)。错误明细查询:

mariadb -usmf -pq1w2e3r4 smf -e \
  "SELECT id_error, FROM_UNIXTIME(log_time) t, ip, LEFT(message,100) msg FROM smf_log_errors ORDER BY id_error DESC LIMIT 5;"

7.3 备份(实测)

mariadb-dump -usmf -pq1w2e3r4 smf > /tmp/smf_backup.sql
ls -lh /tmp/smf_backup.sql
head -3 /tmp/smf_backup.sql

实测回显:

-rw-r--r-- 1 root root 165K Nov  2 10:01 /tmp/smf_backup.sql
/*M!999999\- enable the sandbox mode */ 
-- MariaDB dump 10.19-11.4.13-MariaDB, for debian-linux-gnu (x86_64)
--

论坛全部数据(帖子、会员、配置、任务队列)都在库里,mariadb-dump 单文件即完整备份;附件与头像属文件目录,备份时另行打包 attachments/、avatars/。

💡 技术拓展:常见备份形态对比——

方式特点适用
逻辑备份(mariadb-dump,本文)跨版本可移植、可单表恢复、恢复需重放 SQL中小论坛日备
文件级冷拷贝停写后打包数据目录,恢复最快迁移/灾难快照
主从复制连续保护高可用,但防不了误删

本文场景为单机论坛全量日备,选逻辑备份。

7.4 恢复与验证(实测)

mariadb -usmf -pq1w2e3r4 smf < /tmp/smf_backup.sql && echo restore_ok
restore_ok

恢复后验证(表数与业务行数应与备份时一致):

mariadb -usmf -pq1w2e3r4 smf -e \
  "SELECT COUNT(*) AS tables_after_restore FROM information_schema.tables WHERE table_schema='smf';
   SELECT COUNT(*) AS topics FROM smf_topics;
   SELECT COUNT(*) AS members FROM smf_members;"
tables_after_restore
73
topics
2
members
1

再从 Web 面复验论坛可访问:

curl -s -o /dev/null -w '%{http_code}\n' http://192.168.1.172:8138/index.php
200

⚠️ 注意:恢复即覆盖当前全部论坛数据,操作前先做 7.3 反向备份;恢复完成后执行 8.2 清缓存,避免页面缓存与库内容不一致。

7.5 定期备份(推荐配置)

新建 /etc/cron.d/smf-backup,每日 03:00 全量备份并保留 gzip:

0 3 * * * root mariadb-dump -usmf -pq1w2e3r4 smf | gzip > /backup/smf_$(date +\%F).sql.gz

⚠️ 注意:crontab 中的 % 是注释符,日期格式必须写成 \%F(cron 标准行为)。备份账号建议用只备份所需权限的专用账号,而非论坛主账号。

八、文件层运维命令

8.1 维护模式开关(实测)

开维护(访客挡在门外,管理员仍可进入处理后台):

sed -i 's/^\$maintenance = 0;/\$maintenance = 1;/' /var/www/html/Settings.php
grep '^\$maintenance' /var/www/html/Settings.php
curl -s -o /dev/null -w 'guest index: %{http_code}\n' http://192.168.1.172:8138/index.php

实测回显:

$maintenance = 1;
guest index: 503

恢复访问:

sed -i 's/^\$maintenance = 1;/\$maintenance = 0;/' /var/www/html/Settings.php
sleep 3
curl -s -o /dev/null -w 'guest index: %{http_code}\n' http://192.168.1.172:8138/index.php
guest index: 200

⚠️ 注意:改完约 2 秒才生效(OPcache 文件重校验周期,实测),脚本里加 sleep 再验证,勿误判「改了没生效」。$maintenance = 2 是完全关闭档(连管理员也挡),三态差异详见《SMF 2.1.8 配置参数详解》5.2 节。

8.2 清理缓存(实测)

rm -f /var/www/html/cache/*.db3
ls -l /var/www/html/cache/

实测回显(删除后目录仅剩守卫文件与错误时间戳,均为常驻文件):

total 8
-rw-r--r-- 1 www-data www-data  28 Nov  2 09:23 db_last_error.php
-rw-rw-r-- 1 www-data www-data 321 Oct 11 13:35 index.php

解读:默认配置($cache_enable = 0)不写缓存数据文件,实测删除后连续浏览首页/版块/帖子/统计/搜索页均不再生成;后台启用 SQLite 缓存后,cache/SQLite3Cache.db3 会按需重建(本实例实测 16 KB)。改 smf_settings 或 $boardurl 后用它强制页面重渲染。

8.3 目录权限

Web 进程账号为 www-data(实测 UID 33)。软件包安装、附件上传、缓存写入失败九成是目录不可写,修复:

chown -R www-data:www-data /var/www/html/cache /var/www/html/Packages /var/www/html/attachments /var/www/html/avatars

Settings.php 本身建议收紧到 640(属主含 Web 进程可读即可,安装向导完成后程序不再写它,仅升级向导需要)。

8.4 Web 访问日志

tail -5 /var/log/apache2/access.log

实测回显(节选,覆盖维护模式与发帖两类关键状态):

10.89.64.1 - - [02/Nov/2026:09:31:38 +0000] "GET /index.php HTTP/1.1" 503 8477 "-" "curl/8.5.0"
10.89.64.1 - - [02/Nov/2026:09:32:00 +0000] "GET /index.php HTTP/1.1" 200 10613 "-" "curl/8.5.0"
10.89.64.1 - - [02/Nov/2026:09:33:13 +0000] "POST /index.php?action=post2;board=1 HTTP/1.1" 302 417 "-" "curl/8.5.0"

解读:503 = 维护模式生效(8.1);POST post2 返回 302 = 发帖成功跳转。论坛内部错误日志(比 Apache 错误日志更结构化)在 smf_log_errors 表,查询见 7.2。

九、注意事项

  1. cron 频率下限:不得低于 MAX_CRON_TIME=10 秒,标准每分钟一次;
  2. cron.lock 会静默失效:exit=0 不报错,升级收尾必须 rm(4.6);
  3. 一次 cron 只推进一个到期计划任务:任务积压时多跑几轮;迟到超过半个周期会直接跳过当期(源码 time() + duration/2 > next_time 则 next_time += duration,实测行为一致);
  4. SQL 直改 smf_settings 后必须清缓存(7.1 + 8.2);
  5. update_timezones.php 需要外网:受限网络下耗时超 2 分钟才降级完成(5.1);
  6. fetchSMfiles 外联官方站点:隔离网络环境可在后台计划任务页停用,避免日志噪音;
  7. 敏感值不入仓库:Settings.php 中 $auth_secret、$db_passwd、$image_proxy_secret 泄露等于交出登录态/数据库;
  8. install.php/upgrade.php 常删:站点根目录留存会触发后台 MAJOR SECURITY RISK 告警(本专栏部署篇 4.8 节实测)。

十、常见问题

Q1:SMF 有没有官方管理 CLI(类似 wp-cli)?

没有。管理面 = Web 后台 + 数据库 + 本文四类脚本入口(见「二、工具概览」篇型适配说明)。自动化运维按「四~八章」组合:cron.php 管任务、mariadb 管配置与备份、sed 管文件层开关、SSI.php 管程序化读取。

Q2:cron.php 执行 exit=0 但任务没动?

按序排查:① cache/cron.lock 是否存在(4.6);② smf_settings.next_task_time 是否未到(4.5 置到期法验证);③ 目标任务 disabled 是否为 1(4.4 表)。三者都排除后看 smf_log_errors 有无异常。

Q3:担心 crontab 与网页触发重复执行?

AutoTask 用乐观锁抢占(先以「next_time 仍等于原值」为条件 UPDATE 成新周期值,源码实测),并发只有一个赢家;真正的风险是 crontab 配得过密空转,保持每分钟一次即可。

Q4:怎么确认某个计划任务历史上跑过、跑多久?

smf_log_scheduled_tasks(4.7):time_taken 秒级耗时,FROM_UNIXTIME(time_run) 执行时刻。

Q5:恢复备份后页面行为怪异?

缓存与库不一致。清 cache/*.db3(8.2),并确认 Settings.php 的 $db_* 与恢复目标库一致(7.1 连通验证)。

Q6:SSI 输出为空?

require 路径不对或 PHP 进程读不到 Settings.php(权限)。CLI 下先用 php -r 'require("/var/www/html/SSI.php"); ssi_version();' 冒烟——能打印版本字符串即集成链路正常。

十一、参考链接

SMF 2.1.8 常用 CLI 命令与工具详解 - Quzuo