PmWiki 2.3.38 常用 CLI 命令与工具详解
PmWiki 2.3.38 常用 CLI 命令与工具详解:php -l 语法自检、action=crypt 口令生成、CLI 直跑、备份还原演练、tar 覆盖法升级、pageindex 重建与权限故障诊断,全部命令带实测回显。
PmWiki 2.3.38 常用 CLI 命令与工具详解
目标:把 PmWiki 2.3.38 的运维命令一次讲全。PmWiki 没有 CLI 管理 API、也没有管理后台,日常维护靠三类工具组合:PHP CLI(语法自检、口令散列、页面文件解析)、官方内置
?action入口(crypt 生成口令、diag 诊断)、文件系统命令(备份还原、升级替换、权限修复)。本文全部命令与回显在 Ubuntu 24.04.5 + PHP 8.3.6 实测照抄,备份还原与升级流程为完整演练(非纸面推演)。
一、环境信息
- 操作系统:Ubuntu 24.04.5 LTS(x86_64)
- Web 服务器:Apache 2.4.58(mod_php),systemd 托管
- PHP:8.3.6(cli / libapache2-mod-php8.3)
- PmWiki:2.3.38(安装目录
/var/www/html/pmwiki/,安装过程见《Ubuntu 24.04 安装 PmWiki 2.3.38 指南》) - 配置文件:
/var/www/html/pmwiki/local/config.php(181 行);页面数据wiki.d/(2770,属主 www-data);附件uploads/ - 实测基线:站点已有 1 个内容页(Main.HomePage,rev 207)、1 个附件(uploads/Main/demo-note.txt),wiki.d 含 4 个页面文件
二、前置条件
具备服务器 root 命令行权限;PmWiki 已按安装指南部署且首页可访问(curl -s -o /dev/null -w '%{http_code}\n' http://localhost/pmwiki/pmwiki.php/Main/HomePage 返回 200)。参数含义、默认值与生效链不在本篇展开,见《PmWiki 2.3.38 配置参数详解》。
三、命令与工具总览
| 工具/命令 | 类别 | 用途 | 关键注意 |
|---|---|---|---|
php -l <file> | PHP CLI | 配置/代码语法自检 | 改 config.php 后、reload 前必做 |
?action=crypt | 官方入口 | 生成口令 crypt 散列 | 每次盐随机,散列不同属正常 |
php pmwiki.php | PHP CLI | 命令行直跑引擎 | 输出 HTML、退出码 0,PHP 8.3 有弃用告警 |
php -S 0.0.0.0:8080 | PHP CLI | 内置服务器应急通道 | 单进程,仅体验/应急,禁生产 |
tar czf/xzf | 文件系统 | 全量备份与还原 | 数据 = wiki.d + local + uploads |
tar xzf --exclude | 文件系统 | tar 覆盖法升级 | 必须 reload Apache 才换版本 |
rm wiki.d/.pageindex | 文件系统 | 搜索索引重建 | 搜索/列表变慢时的标准动作 |
chown/chmod | 文件系统 | 权限修复 | wiki.d 需 www-data 可写 + setgid |
php -r '<代码>' | PHP CLI | 页面文件字段解析 | 不经 Web 快速取证页面状态 |
?action=diag | 官方入口 | 全局变量诊断 | 用完即关,长期开启泄露全部配置 |
四、日常维护命令详解
4.1 php -l:配置文件语法自检
PmWiki 是"配置即代码":config.php 改错一个引号全站空白。每次改动后的固定流程是「先语法自检,再 reload,再 curl 验证」:
php -l /var/www/html/pmwiki/local/config.php
systemctl reload apache2
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/pmwiki/pmwiki.php/Main/HomePage
实测回显:
No syntax errors detected in /var/www/html/pmwiki/local/config.php
200
语法错误时 php -l 直接给出文件与行号(实测案例,配置少写一个分号):
PHP Parse error: syntax error, unexpected end of file in /var/www/html/pmwiki/local/config.php on line 183
⚠️ 注意:
php -l只查语法不查逻辑——变量名拼错(如$DefaultPassword少个 s)不会报错,只会静默不生效。逻辑类改动需配合?action=diag核实变量实际值(见 7.4)。
4.2 ?action=crypt:口令散列生成
站点/页面口令一律写 crypt 散列(非明文)。官方内置加密页面,一行 curl 完成生成(实测,示例口令 q1w2e3r4):
curl -s 'http://localhost/pmwiki/pmwiki.php?action=crypt' \
-d 'passwd=q1w2e3r4&n=Main.HomePage&action=crypt' \
| sed 's/<[^>]*>//g' | grep -oE '\$2y\$10\$[A-Za-z0-9./]+'
实测回显:
$2y$10$k2peq5UXQsVokRHvkWC4huOFRaxODbBTwimLrNM.fPQe637qk/5qK
得到散列后写入 config.php 的 $DefaultPasswords['admin'/'edit'/...](配置方法见《PmWiki 2.3.38 配置参数详解》5.2)。每次调用盐随机、散列每次不同,属正常现象。
4.3 php pmwiki.php:CLI 直跑
PmWiki 引擎本体可以从命令行直接执行(无需 Web 服务器),标准输出即完整 HTML 页面:
cd /var/www/html/pmwiki && timeout 10 php pmwiki.php > /tmp/cli-out.html 2>/tmp/cli-err.txt
echo "exit=$?"; head -3 /tmp/cli-out.html; wc -l /tmp/cli-err.txt
实测回显:
exit=0
<!DOCTYPE html>
<html >
<head>
告警文件内容(PHP 8.3 环境下 CLI 直跑的弃用提示,不影响退出码与输出):
PHP Warning: Undefined array key "REQUEST_URI" in /var/www/html/pmwiki/scripts/xlpage-utf-8.php on line 41
PHP Deprecated: preg_match(): Passing null to parameter #2 ($subject) of type string is deprecated in /var/www/html/pmwiki/scripts/xlpage-utf-8.php on line 40
PHP Warning: Undefined array key "REQUEST_URI" in /var/www/html/pmwiki/scripts/forms.php on line 326
💡 说明:CLI 直跑的价值在于「不依赖 Apache 的最小验证」——判断故障出在引擎/数据层还是 Web 层:CLI 输出正常 HTML 而 Apache 页面异常,问题在 Web 服务器配置或权限;CLI 也报错,问题在引擎或数据。PHP 8.3 的 REQUEST_URI 告警源于脚本按 CGI 环境取值,CLI 下不存在该变量,可忽略。
4.4 php -S:内置服务器应急通道
Apache 故障或无 Web 服务器时,用 PHP 内置服务器应急(数据目录与 Apache 方案完全相同,可无缝切换):
cd /var/www/html && php -S 0.0.0.0:8080 > /root/phps.log 2>&1 &
sleep 2
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/pmwiki/pmwiki.php/Main/HomePage
curl -s http://localhost:8080/pmwiki/pmwiki.php/Main/HomePage | grep -oE '<title>[^<]*</title>'
实测回显:
200
<title>PmWiki Demo | Main / HomePage </title>
单进程开发服务器,禁用于公网生产;用完 kill %1 回收。
4.5 scripts/ 内置脚本清单
发布包 scripts/ 目录是引擎的模块库(41 项,2026-10-30 实测 ls),认识它才能「按模块定位问题」:
author.php authuser.php blocklist.php caches.php creole.php crypt.php diag.php
draft.php feeds.php forms.php guiedit.php httpauth.php intermap.txt markupexpr.php
notify.php pagelist.php pagerev.php pgcust.php phpdiff.php pmform.php prefs.php
refcount.php robots.php simuledit.php skins.php stdconfig.php stdmarkup.php
trails.php transition.php upgrades.php upload.php urlapprove.php utils.php
vardoc.php version.php wikistyles.php wikiwords.php
xlpage-iso-8859-13.php xlpage-iso-8859-2.php xlpage-iso-8859-9.php xlpage-utf-8.php
运维高频模块:upload.php(附件)、authuser.php(实名认证)、pagelist.php(列表/搜索)、feeds.php(RSS,默认未启用,?action=rss 返回 404 即此因)、diag.php(诊断)、version.php(版本常量)。模块的启用开关与参数见《PmWiki 2.3.38 配置参数详解》。
五、备份与还原实操
5.1 全量备份:三个目录一条命令
全站数据 = wiki.d/(页面+历史+页面口令)+ local/(配置)+ uploads/(附件)。cookbook/ 是第三方配方可一并打入(出厂即空壳):
tar czf /root/pmwiki-backup-20261030.tar.gz -C /var/www/html \
pmwiki/wiki.d pmwiki/local pmwiki/uploads pmwiki/cookbook
ls -la /root/pmwiki-backup-20261030.tar.gz
tar tzf /root/pmwiki-backup-20261030.tar.gz | head -8
实测回显:
-rw-r--r-- 1 root root 5516 Oct 30 03:44 /root/pmwiki-backup-20261030.tar.gz
pmwiki/wiki.d/
pmwiki/wiki.d/.lastmod
pmwiki/wiki.d/SiteAdmin.Status
pmwiki/wiki.d/Site.AllRecentChanges
pmwiki/wiki.d/Main.HomePage
pmwiki/wiki.d/.htaccess
pmwiki/wiki.d/.pageindex
pmwiki/wiki.d/.flock
💡 说明:PmWiki 无数据库、无缓存依赖,备份即打包目录,这就是文件型引擎「一个目录即全站」的运维优势(选型层面的对比见《PmWiki 介绍与选型指南》)。建议 cron 每日打包并保留 N 天滚动。
5.2 还原演练:模拟 wiki.d 丢失
备份不演练等于没备份。完整还原演练(实测时间线:打包 → 删数据目录 → 观察故障现象 → 解包还原 → 验证):
tar czf /root/pmwiki-backup-d1.tar.gz -C /var/www/html pmwiki/wiki.d pmwiki/local pmwiki/uploads
rm -rf /var/www/html/pmwiki/wiki.d
curl -s "http://localhost/pmwiki/pmwiki.php" | sed 's/<[^>]*>//g' | grep -vE '^\s*$' | head -3
tar xzf /root/pmwiki-backup-d1.tar.gz -C /var/www/html
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/pmwiki/pmwiki.php/Main/HomePage
curl -s http://localhost/pmwiki/pmwiki.php/Main/HomePage | grep -oE '<title>[^<]*</title>'
ls /var/www/html/pmwiki/wiki.d/
实测回显(关键三步):
Redirect ← wiki.d 丢失时首页仅剩重定向壳
200 ← 还原后页面状态
<title>PmWiki Demo | Main / HomePage </title>
Main.HomePage
Main.RecentChanges
Site.AllRecentChanges
SiteAdmin.Status
还原后无需任何重建动作——权限正确时页面立即可用;若还原到新机器,只需补一步 chown -R www-data:www-data wiki.d。
5.3 搜索索引 .pageindex 重建
wiki.d/.pageindex 是搜索与 pagelist 的索引缓存(实测约 227 KB)。页面量大后搜索变慢、或索引疑似损坏时,删除即可自动重建:
ls -la /var/www/html/pmwiki/wiki.d/.pageindex
rm /var/www/html/pmwiki/wiki.d/.pageindex
curl -s -o /dev/null -w '%{http_code}\n' "http://localhost/pmwiki/pmwiki.php?action=search&q=Welcome"
ls -la /var/www/html/pmwiki/wiki.d/.pageindex
实测回显(删除后一次搜索请求触发重建,内容随页面快照更新为 251 KB):
-rw-rw-r-- 1 www-data www-data 227478 Oct 30 03:53 /var/www/html/pmwiki/wiki.d/.pageindex
200
-rw-rw-r-- 1 www-data www-data 251470 Oct 30 05:01 /var/www/html/pmwiki/wiki.d/.pageindex
六、升级与版本替换:tar 覆盖法(实测)
PmWiki 升级 = 换核心文件 + 数据不动。完整演练:先搭一个 2.3.37 旧版本站点(数据迁移自 2.3.38 站点),再用 tar 覆盖法升级到 2.3.38:
cd /var/www/html
# 第 1 步:解出旧版本并迁移数据(模拟旧版存量站点)
tar xzf pmwiki-2.3.37.tgz && mv pmwiki-2.3.37 pmwiki-upg
cp -a pmwiki/wiki.d pmwiki/local pmwiki/uploads pmwiki-upg/
chown -R www-data:www-data pmwiki-upg/wiki.d pmwiki-upg/uploads
# 第 2 步:确认升级前版本
grep -m1 "Version = " pmwiki-upg/pmwiki.php
curl -s "http://localhost/pmwiki-upg/pmwiki.php?action=diag" | grep -oE 'Version\] => pmwiki[^<"]{0,20}' | head -1
# 第 3 步:tar 覆盖核心文件,排除数据目录
tar xzf pmwiki-2.3.38.tgz -C pmwiki-upg --strip-components=1 \
--exclude=wiki.d --exclude=local --exclude=uploads
# 第 4 步:reload 使 opcache 释放旧版本代码,再验证
systemctl reload apache2
curl -s "http://localhost/pmwiki-upg/pmwiki.php?action=diag" | grep -oE 'Version\] => pmwiki[^<"]{0,20}' | head -1
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/pmwiki-upg/pmwiki.php/Main/HomePage
grep -c "部署验证" pmwiki-upg/wiki.d/Main.HomePage
实测回显(关键节点):
$Version = '2.3.37'; ← 升级前代码版本
Version] => pmwiki-2.3.37
Version] => pmwiki-2.3.38 ← 覆盖 + reload 后
200 ← 页面正常
4 ← 原内容页数据完整保留
⚠️ 两个实测踩坑点:① 覆盖后立即访问,diag 仍显示旧版本——mod_php 的 opcache 缓存了旧 PHP 文件,
systemctl reload apache2后才生效(本文演练两次复现该现象);②--exclude三目录缺一不可,否则 tar 解包会用空目录/出厂配置覆盖生产数据。升级前先按 5.1 打全量备份。
七、权限诊断实操
7.1 权限故障现场:Cannot acquire lockfile
wiki.d 属主错误是 PmWiki 最高发故障。实测模拟:把 wiki.d 属主改成 root 后访问:
chown -R root:root /var/www/html/pmwiki/wiki.d
curl -s http://localhost/pmwiki/pmwiki.php/Main/HomePage | sed 's/<[^>]*>//g' | grep -vE '^\s*$' | head -4
tail -1 /var/log/apache2/error.log
实测回显(页面报错 + 日志对应):
PmWiki can't process your request
Cannot acquire lockfile
We are sorry for any inconvenience.
[Fri Oct 30 05:01:09.562505 2026] [php:warn] [pid 9813] [client 127.0.0.1:39606] PHP Warning: fopen(wiki.d/.flock): Failed to open stream: Permission denied in /var/www/html/pmwiki/pmwiki.php on line 1138
标准修复动作并验证:
chown -R www-data:www-data /var/www/html/pmwiki/wiki.d
chmod 2770 /var/www/html/pmwiki/wiki.d
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/pmwiki/pmwiki.php/Main/HomePage
实测回显:
200
诊断要点:「Cannot acquire lockfile」= 进程写不了 wiki.d/.flock 锁文件;页面空白/500 且日志无记录 = config.php 语法问题(4.1);两者都修不好再用 ?action=diag 深查。
7.2 页面级口令检查
页面级口令(?action=attr 设置)以 passwd 开头的键持久化在页面文件里;站点级口令则在 config.php。一行命令区分某页的权限来源:
grep -ac "^passwd" /var/www/html/pmwiki/wiki.d/Main.HomePage
grep -n "DefaultPasswords" /var/www/html/pmwiki/local/config.php | grep -v "^.*#"
实测回显:
0
174:$DefaultPasswords['admin'] = '$2y$10$k2peq5UXQsVokRHvkWC4huOFRaxODbBTwimLrNM.fPQe637qk/5qK';
181:$DefaultPasswords['edit'] = '$2y$10$k2peq5UXQsVokRHvkWC4huOFRaxODbBTwimLrNM.fPQe637qk/5qK';
本实测站点 passwd 计数 0 = 无页面级口令,权限全部来自站点级配置;若某页被单独 attr 上锁,计数 ≥1,可直接看到散列。编辑验证口令是否生效:
curl -s "http://localhost/pmwiki/pmwiki.php/Main/HomePage?action=edit" | sed 's/<[^>]*>//g' | grep -iE "password" | head -2
实测回显(未认证被拦,口令门禁生效):
Password required
Password:
7.3 php -r:页面文件字段解析
页面文件是 key=value 行式结构,php -r 不经 Web 快速取证页面名与修订号(比 grep 更稳,天然处理 urlencoded):
php -r '$f=file_get_contents("/var/www/html/pmwiki/wiki.d/Main.HomePage");
preg_match("/^name=(.+)$/m",$f,$m); preg_match("/^rev=(.+)$/m",$f,$r);
echo "page=".trim($m[1])." rev=".trim($r[1]).PHP_EOL;'
实测回显:
page=Main.HomePage rev=207
rev 是页面修订计数(含历史 diff 的代际),配合 diff: 时间戳键可判断「最近一次编辑是什么时候、改了什么」。
7.4 ?action=diag 与 PHP 模块核对
?action=diag 输出全部 $GLOBALS(约 122 KB),是核实参数实际生效值的官方手段——临时开启方法与安全注意见《PmWiki 2.3.38 配置参数详解》3.2,用完必须关闭。PHP 运行环境核对(官方要求 pcre/session/spl,中文站必备 mbstring):
php -m | wc -l
php -m | grep -iE '^(mbstring|openssl|pcre|session|spl|xml)$'
实测回显:
45
mbstring
openssl
pcre
session
SPL
xml
八、常见问题(FAQ)
Q1:改了 config.php 全站空白?
语法错误,php -l 定位行号修复(4.1 实测案例 line 183)。预防:改动后先 php -l 再 reload。
Q2:升级/改配置后行为不变?
opcache 缓存旧代码,systemctl reload apache2 后验证。本文升级演练即靠 reload 使 2.3.37 → 2.3.38 生效(第六节)。
Q3:页面报「Cannot acquire lockfile」?
wiki.d 不可写(7.1 实测:属主 root 后必现)。修复:chown -R www-data:www-data wiki.d && chmod 2770 wiki.d。
Q4:搜索很慢或结果缺失?
重建索引:删除 wiki.d/.pageindex 后访问一次搜索页自动重建(5.3 实测)。索引是纯缓存,删除无数据风险。
Q5:?action=rss 返回 404?
Feed 模块默认未启用,在 config.php 追加 include_once("scripts/feeds.php"); 并 reload 后,?action=rss(RSS)与 ?action=atom(Atom)可用。
Q6:CLI 直跑 pmwiki.php 报 REQUEST_URI 告警? PHP 8.3 下 CLI 环境无该 CGI 变量所致(4.3 实测),退出码仍为 0、HTML 输出正常,可忽略;生产访问走 Apache/mod_php 无此告警。
九、参考链接
- PmWiki 官网:https://www.pmwiki.org/
- 官方升级文档(在线版):https://www.pmwiki.org/wiki/PmWiki/Upgrades
- 备份与安全属性依据:2.3.38 发布包
scripts/wikistyles.php、scripts/upload.php与wiki.d/实测文件结构 - 站内相关:《Ubuntu 24.04 安装 PmWiki 2.3.38 指南》|《PmWiki 2.3.38 配置参数详解》|《PmWiki 介绍与选型指南》|同类引擎命令对照可看 《Otter Wiki 2.26.1 常用命令与页面语法详解》