AmuseWiki 2.611 常用 CLI 命令与工具详解

AmuseWiki 2.611 全部 21 个 CLI 子命令与 amusewiki 统一入口包装器实测详解:无停机重启、站点克隆导入导出、站点选项、nginx 配置生成、索引聚合与编译自检逐命令回显,含 mode 保留变量回滚、export-titles 缺依赖、check-compiler PATH 三条排障实录。

AmuseWikiAmuseWikiWikiPerl2026/11/01

AmuseWiki 2.611 常用 CLI 命令与工具详解

目标:把 AmuseWiki 2.611 的 21 个命令行子命令(/usr/bin/amusewiki-* 全家桶)与 amusewiki 统一入口包装器逐一讲清——每个命令给出真实用法、实测回显与运维场景,并沉淀三条排障实录(mode 保留变量回滚、export-titles 缺依赖、check-compiler 的 PATH 依赖)。安装部署见 《AmuseWiki Docker Compose 部署指南》,站点级参数含义见 《AmuseWiki 2.611 配置参数详解》,软件定位与选型见 《AmuseWiki 介绍与选型指南》。

一、环境信息

  • 服务器:Debian 12 (bookworm) x86_64,主机名 amusewiki.local
  • 应用:AmuseWikiFarm 2.611(Debian 包 amusewiki 2.611-1+amw1,官方仓库 deb.amusewiki.org);官方最新稳定版 2.619(Changes 2026-10-10,2026-11-01 实查),本篇命令与回显以 2.611 实测为准
  • 应用根目录:/var/lib/amusewiki(amusewiki 用户属主),内含 repo/(站点 git 仓库树)、dbic.yaml(数据库连接)、xapian/(全文索引)、staging/、thumbnails/、log/、shared/、fontspec.json、log4perl.conf 等
  • CLI 分布:21 个子命令位于 /usr/bin/amusewiki-<action>;root 统一入口包装器位于 /usr/sbin/amusewiki;手册页以 .1p.gz 形式安装(amusewiki-bootstrap-archive.1p.gz、amusewiki-check-compiler.1p.gz、amusewiki-clone-site.1p.gz、amusewiki-create-doc-site.1p.gz、amusewiki-export-titles.1p.gz、amusewiki-generate-meta-config.1p.gz、amusewiki-generate-nginx-conf.1p.gz、amusewiki-generate-static-indexes.1p.gz 等)
  • 相关 systemd 单元:amusewiki-web.service(Plack FCGI,监听 unix socket /var/lib/amusewiki/amusewiki.socket)、amusewiki-jobber.service(作业队列守护)、amusewiki-nginx-reload.path / amusewiki-nginx-reload.service
  • 演示管理账号:admin / q1w2e3r4(root 角色)

二、工具概览

2.1 子命令全清单(实测)

ls /usr/bin/amusewiki-* 实测共 21 个子命令,按运维职能分组如下:

分组子命令职能
站点生命周期create-doc-site、clone-site、bootstrap-archive初始化根站点;站点配置导出/导入;重建文本库与编译产物
站点配置操作set-site-variable、include-path、whitelist-ip、generate-meta-config设置 site 选项;文件包含路径;IP 白名单;生成农场 meta 配置
索引与聚合generate-static-indexes、populate-monthly、oai-pmh-index、export-titles静态索引页;月度归档页;OAI-PMH 元数据收割索引;标题清单导出 XLSX
接入层generate-nginx-conf、letsencrypt生成 farm nginx 配置;ACME 证书更新
认证与导入reset-password、import-redirections重置用户密码;导入旧链接重定向规则
升级与校验upgrade-db、upgrade-lexicon、check-compiler、populate-webfonts数据库 schema 升级;翻译词库更新;PDF 编译链路自检;Web 字体安装
作业队列jobber、jobber-execjobber 队列守护入口与客户端

注意两点(实测):

  • 没有 amusewiki import / amusewiki export 这类裸命令——站点配置的导入导出是 clone-site import / clone-site export 子动作;
  • reset-password 与 import-redirections 不支持 --help(实测报错见 4.6 / 4.7)。

2.2 统一入口包装器 amusewiki

Debian 包在 /usr/sbin/amusewiki 安装了一个 root 入口包装器,把任意 amusewiki-<action> 以 amusewiki 用户身份、在正确目录下执行。裸跑(无参数)打印帮助并退出码 1,实测回显:

Usage: amusewiki action [ argument1, argument2]

Run the amusewiki scripts as user amusewiki in the correct directory.

Available commands:
amusewiki bootstrap-archive
amusewiki check-compiler
amusewiki clone-site
amusewiki create-doc-site
amusewiki export-titles
amusewiki generate-meta-config
amusewiki generate-nginx-conf
amusewiki generate-static-indexes
amusewiki import-redirections
amusewiki include-path
amusewiki jobber
amusewiki jobber-exec
amusewiki letsencrypt
amusewiki oai-pmh-index
amusewiki populate-monthly
amusewiki populate-webfonts
amusewiki reset-password
amusewiki set-site-variable
amusewiki upgrade-db
amusewiki upgrade-lexicon
amusewiki whitelist-ip

amusewiki shell

The shell subcommand will start a shell with the amusewiki user

See man amusewiki-<action> for usage of each command
or run amusewiki <action> --help

Other useful commands:

amusewiki [ start | stop | restart ]

start and stop actions simply call systemctl, while the restart action
performs a restart without downtime (so being a bit more useful than
just "systemctl restart amusewiki-web amusewiki-jobber"

包装器对普通子命令的转发逻辑就两行(脚本实测):

cd /var/lib/amusewiki
sudo -u amusewiki -- amusewiki-$action "$@"

即自动切到应用根目录、降权为 amusewiki 用户执行,因此 root 下 amusewiki bootstrap-archive demo 等价于以 amusewiki 用户在 /var/lib/amusewiki 里跑 /usr/bin/amusewiki-bootstrap-archive demo。

2.3 特殊 action:shell / start / stop / restart

  • amusewiki shell:exec su - amusewiki,直接进入应用用户交互 shell;
  • amusewiki start / stop:分别透传 systemctl start|stop amusewiki-web amusewiki-jobber;
  • amusewiki restart:无停机重启(见 4.1 实测),比直接 systemctl restart 多一段"先起备胎、再换正主、最后收备胎"的流程。

三、前置条件

  1. 工作目录:多数脚本要求从应用根目录(repo/ 所在目录)执行——bootstrap-archive、include-path、whitelist-ip 的 --help 均原文强调 "You need to be in the root directory of the application, i.e. where 'repo' is located."。用 2.2 的包装器可免除此操心。

  2. 执行身份:root 走 /usr/sbin/amusewiki 包装器;amusewiki 用户直接跑 /usr/bin/amusewiki-*。反过来不行——实测以 amusewiki 用户尝试 sudo -u amusewiki /usr/bin/amusewiki-bootstrap-archive --help 被拒:

    Sorry, user amusewiki is not allowed to execute '/usr/bin/amusewiki-bootstrap-archive --help' as amusewiki on amusewiki.local.
    
  3. 数据库连接:create-doc-site、upgrade-db 等需要当前目录(或 ~/.dbic.yaml)存在 amuse 段的数据库配置(见配置详解篇的 dbic.yaml 一节)。

  4. 外部依赖:check-compiler 要求 xelatex 在 PATH(TeX Live);export-titles 要求 Perl 模块 Excel::Writer::XLSX(缺依赖排障见 6.2)。

四、各工具详解

4.1 amusewiki restart——无停机重启(实测全流程)

amusewiki restart 的机制:先在 socket 旁拉起一个临时 plackup FCGI 备胎进程组(--nproc 3),确认其 PID 文件就绪后 systemctl restart amusewiki-web amusewiki-jobber,等正主起来再把备胎优雅终止。实测完整回显:

1. waiting 10 seconds for the backup app to come up
FastCGI: manager (pid 803): initialized
FastCGI: manager (pid 803): server (pid 806) started
FastCGI: manager (pid 803): server (pid 807) started
Started copy of the application with pid 803.
If this script exits prematurely, please kill it yourself.
Waiting for the backup app to come up...
Restarting the apps
Waiting for the real app to come up...
Stopping the backup app 803
Trying to kill 803
FastCGI: server (pid 806): initialized
FastCGI: server (pid 807): initialized
FastCGI: server (pid 808): initialized
FastCGI: manager (pid 803): server (pid 808) started
FastCGI: manager (pid 803): received signal TERM
FastCGI: manager (pid 803): sending TERM to PIDs, 806 808 807
FastCGI: manager (pid 803): server (pid 808) exited with status 0
FastCGI: manager (pid 803): server (pid 806) exited with status 0
FastCGI: manager (pid 803): server (pid 807) exited with status 0
FastCGI: manager (pid 803): dying: safe exit from signal TERM
All done, no errors

重启后核验(80 端口仍在监听、三个单元均 active):

LISTEN 0      511          0.0.0.0:80         0.0.0.0:*
LISTEN 0      511             [::]:80            [::]:*
active
active
active

若备胎 PID 文件始终不出现,脚本以退出码 2 终止并提示 Cannot find PID file for temporary amusewiki process, expecting /var/lib/amusewiki/.amusewiki-backup.tmp.pid;若中途异常退出,备胎进程需手工 kill(帮助原文 "If this script exits prematurely, please kill it yourself.")。

4.2 create-doc-site——初始化根站点

--help 实测回显:

Usage:
      amusewiki-create-doc-site

    Try to clone the repository of amusewiki.org, creating an initial site
    with with documentation and a root user as well, so you are able to
    login and create new sites/users from there.

    It needs to be called from the application root directory, from where
    both the web-server and the jobber should start.

    It creates all the needed directories, but it needs to be able to
    connect to the database. This means that you need to have dbic.yaml in
    the current directory, or in ~/.dbic.yaml with the "amuse" stanza with
    the database settings.

  Options:
    --hostname
        Defaults to "amusewiki.`hostname -d`"

    --username
        The root user. Its name defaults to amusewiki

    --password
        The root user's password. Automatically generated if not provided.

要点:它从 amusewiki.org 克隆文档仓库生成初始站点 + root 用户,是全新安装后的第一条命令;三个选项 --hostname/--username/--password 的完整初始化实测(含 Root username: "admin" 回显)见部署篇。注意 --help 文案里 "with with" 是上游原文笔误。

4.3 bootstrap-archive——重建文本库与编译产物

--help 实测回显:

Usage:
    Usage: amusewiki-bootstrap-archive [ --refresh | --recompile | --xapian
    | --help ] [ <site-id>, <site-id-2>, ... ]

    The list of site ids is optional. If not passed, all the sites will be
    built.

    You need to be in the root directory of the application, i.e. where
    'repo' is located.

  Options:
    Without any option, bootstrap the text database and the build the files
    which need compilation.

    --help
        Print this help and exit.

    --refresh
        Same as without options, but checking for outdated files in the
        database first. You can save a lot of I/O.

    --xapian
        Do not perform any compilation or db operation, but only reindex the
        xapian database.

站点参数可选,不传则全农场重建。对 demo 站点全量重建实测:

Processing demo
No language found, assuming english
Custom directives: category, topic demo
Inserting data for /var/lib/amusewiki/repo/demo/h/ho/hello.muse
Updating hello in Xapian db
Updating title and category sorting
Updated 0 records in 0 seconds
Scheduled static indexes generation

增量模式 --refresh 实测(跳过未变更文件,I/O 明显更少):

Processing demo
Updating title and category sorting
Updated 0 records in 0 seconds
Scheduled static indexes generation

场景:git 仓库被外部批量导入/搬迁后、Xapian 索引与数据库失真时、升级后需重编译输出文件时。末行 Scheduled static indexes generation 说明它把静态索引生成排入 jobber 队列异步执行(见 4.19)。

4.4 clone-site——站点配置导出/导入

--help 实测回显:

Usage:
    Importing configuration, users, links, categories from files:

     amusewiki-clone-site import [ file1.yml , file2.yml, ... ]

    Exporting the same to files:

     amusewiki-clone-site export [ id1, id2, id3, .... ]

    When exporting, the files will be left in temporary directory. Without
    arguments, all the sites will be exported.

  Options:
    --directory /path/to/dir
        Accepted both by export and by import. On export, dump the files
        there. On import, import all the YAML file from the specified
        directory.

    --bootstrap
        Import only option. After the import, bootstrap the site (file
        compilation, add texts to nodes, add annotations). Recommended,
        unless you are just syncing site configurations.

导出实测(--directory /tmp/amw-export,不带站点参数=全农场):

Using directory /tmp/amw-export for output
Exported site amw to /tmp/amw-export/amw.yaml
Exported site demo to /tmp/amw-export/demo.yaml
amw.yaml
demo.yaml

导入实测——先手工准备第三个站点 t1 的 YAML,clone-site import 回显:

canonical: t1.localhost
id: t1
sitename: T1 Sandbox
Please place the site tree into /var/lib/amusewiki/repo/t1 at /usr/bin/amusewiki-clone-site line 109.
Importing /tmp/exp2/t1.yaml
admin already exists, adding it to the site

两个关键行为:① 导入只建配置(site 记录、用户、链接、分类),文本树要自己放——脚本停下来提示把站点树放进 /var/lib/amusewiki/repo/<id>;② 已存在的用户(如 admin)会被挂到新站点而非重建。导入后站点清单核验:

amw|localhost|AmuseWiki documentation
demo|demo.localhost|Demo Library
t1|t1.localhost|T1 Sandbox

跨服务器迁移时,把 export 的 YAML 与 repo/<id> 树一起带走,再 import --bootstrap。

4.5 set-site-variable——设置站点选项

--help 实测回显:

Usage:
    Usage: amusewiki-set-site-variable [ --all | site_id site_id_2 ... ]
    --set name=value [ --set ... ]

    Set a site option from the command line. The site IDs should be passed
    as arguments, or you can use "--all" to affect all of them.

    The option name/value pairs should be passed to "--set" arguments as
    shown in the example.

    You can pass as many pairs you want.

    With the "--help" option, show this help and exit.

非保留变量实测(对 demo 站点改 siteslogan 与 bb_page_limit,随后回滚原值):

Updating demo siteslogan => CLI tuned
Updating demo bb_page_limit => 500
500|CLI tuned
Updating demo bb_page_limit => 1000
Updating demo siteslogan => Demo farm site

可设的 name 即 site 表列名 / site_options 键名(含义见配置详解篇)。例外:mode、id、last_updated 是保留变量,CLI 改 mode 会打印 Updating ... 后 die 并回滚——完整实录与正确做法见 6.1。

4.6 reset-password——重置用户密码

实测 --help 不支持,直接 die:

Unknown option: help
Died at /usr/bin/amusewiki-reset-password line 55.

裸跑则打印真实用法:

Usage: /usr/bin/amusewiki-reset-password <username> [<password>]

用法:amusewiki-reset-password admin q1w2e3r4(位置参数:用户名 + 可选新密码)。忘记管理密码、或部署篇环境变量批量改密之外的单点改密,都用它。

4.7 import-redirections——导入重定向规则

实测 --help 同样不支持:

--help not found at /usr/bin/amusewiki-import-redirections line 43.

裸跑提示第一个位置参数必须是站点 ID:

Missing site id at /usr/bin/amusewiki-import-redirections line 39.

场景:从别的 wiki 平台搬家时,把"旧链接 → 新 canonical"的重定向清单批量导入到指定站点,避免外部死链。详细参数以手册页 amusewiki-import-redirections(1p) 为准。

4.8 include-path——文件包含路径白名单

--help 实测回显(安全警告是原文重点):

Usage:
    Usage: amusewiki-include-path [ --all | --site <site_id> ] [ --add path
    ] [ --remove path ] [ --reset ]

    You need to be in the root directory of the application, i.e. where
    'repo' is located.

    Please note that if you include directories like "/", "/etc", "/home"
    and alike, nothing is stopping the application to include sensitive
    files which are readable by the application itsef.

    To mitigate this potential security problem, there is no web interface
    to set the include paths and they can be manipulated only by DB access
    or via this script.

    You are advised to enable this feature only on private sites or on sites
    where only trusted users have write access.

    This feature is disabled by default.

  Options:
    --help
        Print this help and exit.

    --site <site_id>

实测对 demo 站点添加 /var/lib/amusewiki/shared 后查询、再 --reset 清空:

Site: demo include paths:
 - /var/lib/amusewiki/shared

Resetting include paths for demo
0

用途:muse 源文件里的 INCLUDE 指令允许引用磁盘上的共享文件(如跨站点公共页脚)。配置存于 site_options 表;官方明确默认关闭、无 Web 界面、仅私有/可信站点启用。

4.9 whitelist-ip——IP 白名单

--help 实测回显:

Usage:
    Usage: amusewiki-whitelist-ip [ --all | --site <site_id> ] [ --add ip ]
    [ --remove ip ] [ --reset ] [ --list ]

    You need to be in the root directory of the application, i.e. where
    'repo' is located.

  Options:
    --help
        Print this help and exit.

    --site <site_id>
        Repeatable. Set the site(s) you want to operate on. Use "--all" if
        you want to operate on every site.

    --add <ip>
        Repeatable. Add the given ip to the whitelist

    --remove <ip>
        Repeatable. Remove the given ip from the whitelist

    --reset
        Clear the whitelist.

--list 实测回显(站点 / IP / 角色三列):

demo 10.89.60.1 root

白名单内的来源 IP 可免登录获得指定角色(此处为上游网关地址获 root),适合内网只读农场或爬虫出口固定 IP 的免密放权。

4.10 generate-nginx-conf——生成 farm nginx 配置

实测回显(脚本不直接改配置,而是打印三条 root 手工步骤):

# please execute as root:
diff -Nu /etc/nginx/sites-enabled/amusewikidebian /tmp/nginx-amusewiki-aPV7Ipvj/amusewikidebian
cat /tmp/nginx-amusewiki-aPV7Ipvj/amusewikidebian > /etc/nginx/sites-enabled/amusewikidebian
nginx -t && service nginx reload

机制:按当前全部激活站点的 canonical 域名渲染一份完整的 farm server 配置到临时目录(三站点环境下再次实测输出同构)。新增/改名站点后跑它,人工 diff 确认再覆盖并重载 nginx——这是多站点按域名路由的接入层根基(server_name 与 site 表 canonical 一一对应,见配置详解篇)。

4.11 索引与聚合三件套

generate-static-indexes(帮助仅一行 Usage: amusewiki-generate-static-indexes [ <site-id>, ... ]),对 demo 实测:

Processing demo
Generated main in 0 seconds
Stored file list in 0 seconds
Stored RSS feed in 0 seconds

populate-monthly(帮助 Usage: amusewiki-populate-monthly [ <site-id>, ... ])实测:

Processing demo

oai-pmh-index(帮助 Usage: amusewiki-oai-pmh-index [ --all | site_id_1 [ site_id_2 site_id_3 ...] ])实测:

0.01581 [0.01359] Processing 6 files for texts
0.017139 [0.014921] Processing 6 (including attachments)
0.019937 [0.017718] Collected existing records
0.042022 [0.039799] Updated 6 records
0.04381 [0.04158] Handled removals and finished
Updated OAI-PMH records for demo in 0 seconds

三者分别维护站点首页静态目录/RSS、按月归档页、OAI-PMH 元数据收割记录(对接数字图书馆基础设施)。日常无需手跑——bootstrap 与 jobber 会自动调度(4.3 末行即例证),数据修复时才手工触发。

4.12 export-titles——标题清单导出 XLSX

--help 实测回显:

Usage:
     amusewiki-export-titles <SITE-ID> <FILE.xlsx>

    Excel::Writer::XLSX is required for this script to work (in debian:
    "libspreadsheet-xlsx-perl")

注意帮助里给的 Debian 包名是错的(libspreadsheet-xlsx-perl 是读库,本脚本需要写库 Excel::Writer::XLSX),缺依赖实测报错与修复全程见 6.2。修复后对 demo 实测成功:

exit=0
/tmp/titles.xlsx: Microsoft Excel 2007+
-rw-r--r-- 1 amusewiki amusewiki 5831 Nov  1 11:20 /tmp/titles.xlsx

用途:把站点全部文本标题导出为 Excel 编目清单(图书馆场景的馆藏盘点)。

4.13 generate-meta-config——生成农场 meta 配置

实测 --help 不打印帮助,而是直接执行生成动作:

Configuration file left in /tmp/rRPU1V10Yv/amw-meta-config.yml

生成物内容(实测全文):

---
meta:
  adult_content: 0
  description: Site Description
  icon_url: https://amusewiki.org/favicon.ico
  is_private: 0
  name: Site Name
sites: []

这是农场向 amusewiki.org 聚合目录注册用的元数据模板,sites 列表由实际站点填充。使用时注意:--help 有副作用(见五、注意事项)。

4.14 populate-webfonts——安装 Web 字体

实测 --help 同样直接执行:

Checking fontspec.json

按应用根目录 fontspec.json(字体清单,见配置详解篇)下载/安装站点 CSS 引用的 web 字体。

4.15 upgrade-db——数据库 schema 升级

--help 回显:

Usage:
      amusewiki-upgrade-db

    Upgrade the amusewiki database if needed.

实测执行:

DDLs dir is /usr/share/perl5/AmuseWikiFarm/dbicdh
Checking if database is up-to-date: YES

升级包版本后(或怀疑 schema 落后时)跑它;DDL 迁移脚本目录为 /usr/share/perl5/AmuseWikiFarm/dbicdh。amusewiki-jobber 启动包装里也会后台带一次 upgrade-db(见 4.19),双保险。

4.16 upgrade-lexicon——翻译词库更新

--help 实测回显(注意其 Usage 行误写成了 bootstrap-archive,上游文案 bug,参数语义以正文为准):

Usage:
    Usage: amusewiki-bootstrap-archive [ --help ] repo1, [ repo2, repo3 ]

    Usually you would do:

     amusewiki-bootstrap-archive repo/*

    from the application home.

    If the target po file exist, it will be merged with the entries from
    lexicon.json, which will take precendece (otherwise you shouldn't use
    this script at all).

用途:把 lexicon.json 的新词条合并进站点 po 翻译文件(本地化维护),已存在的条目以 lexicon.json 为准。

4.17 check-compiler——PDF 编译链路自检

本质是一套 68 项的 Test::More 自检(1..68)。未装/不在 PATH 的 xelatex 时实测失败形态:

# saving output to /tmp/QLyO8BRLpr
1..68
Working on mk.muse file in /tmp/QLyO8BRLpr
sans font not found, using the default
mono font not found, using the default
main font not found, using the default
Command 'xelatex' not found in /usr/local/sbin, /usr/local/bin, /usr/sbin, /usr/bin, /sbin, /bin at /usr/share/perl5/Text/Amuse/Compile/File.pm line 860.
Failure to compile /tmp/QLyO8BRLpr/mk.muse
not ok 1 - /tmp/QLyO8BRLpr/mk.pdf exists
#   Failed test '/tmp/QLyO8BRLpr/mk.pdf exists'
#   at /usr/bin/amusewiki-check-compiler line 54.
ok 2 - /tmp/QLyO8BRLpr/mk.tex exists
Couldn't find the language in the tex body at /usr/bin/amusewiki-check-compiler line 61.
# Looks like your test exited with 255 just after 2.

把 TeX Live 的 bin 目录加入 PATH 后实测:

# saving output to /tmp/o_JwnZZvMk
1..68
Working on tl.muse file in /tmp/o_JwnZZvMk
sans font not found, using the default
mono font not found, using the default
main font not found, using the default
* Created tl.pdf
ok 1 - /tmp/o_JwnZZvMk/tl.pdf exists
ok 2 - /tmp/o_JwnZZvMk/tl.tex exists
Couldn't find the language in the tex body at /usr/bin/amusewiki-check-compiler line 61.
# Looks like your test exited with 255 just after 2.

判读要点:* Created tl.pdf + 前两项 ok 即证明编译链路正常;其后的 Couldn't find the language in the tex body(line 61)与 exit 255 是脚本自身的语言检测缺陷,不代表编译失败(详见 6.3)。

4.18 letsencrypt——ACME 证书更新

--help 实测回显:

Usage:
    amusewiki-letsencrypt [ --check-only --help ]

    Update the acme certificates.

配合 site 表的 acme_certificate 开关与 ssl_* 字段使用(字段含义见配置详解篇):对启用了 ACME 的站点批量续签证书,--check-only 只检查不续签。

4.19 jobber / jobber-exec——作业队列

amusewiki-web.service 与 amusewiki-jobber.service 成对运行:前者是 Plack FCGI 站点进程,后者消费编译作业队列(PDF/EPUB 输出、静态索引、月度页等全部异步任务)。

ExecStart 指向的 /usr/bin/amusewiki-jobber 实际是启动包装脚本:先把 repo/、thumbnails/、staging/、db 文件等属主修正为 amusewiki:amusewiki、拉起 nginx、后台执行一次 amusewiki-upgrade-db,最后 exec amusewiki-jobber-exec "$@" 进入真正的 jobber 客户端。因此 CLI 侧 amusewiki jobber-exec <jobber 子命令> 即可透传 jobber 原生管理指令(jobber 是独立的上游作业守护项目,子命令语义见其文档)。

运维观察点主要是日志,实测 tail jobber 日志(新建 t1 站点后,输出格式为 时间 INFO - 模块 - 源文件:行 - 消息):

2026-11-01 11:23:12 INFO - AmuseWikiFarm.Schema.Result.Site - /usr/share/perl5/AmuseWikiFarm/Schema/Result/Site.pm:1481 - pdf for t1 is disabled
2026-11-01 11:23:12 INFO - AmuseWikiFarm.Schema.Result.Site - /usr/share/perl5/AmuseWikiFarm/Schema/Result/Site.pm:1481 - sl_pdf for t1 is disabled
2026-11-01 11:23:12 INFO - AmuseWikiFarm.Schema.Result.CustomFormat - /usr/share/perl5/AmuseWikiFarm/Schema/Result/CustomFormat.pm:864 - c9 is without format code
2026-11-01 11:23:12 INFO - AmuseWikiFarm.Schema.Result.CustomFormat - /usr/share/perl5/AmuseWikiFarm/Schema/Result/CustomFormat.pm:864 - c10 is without format code
2026-11-01 11:23:12 INFO - AmuseWikiFarm.Schema.Result.CustomFormat - /usr/share/perl5/AmuseWikiFarm/Schema/Result/CustomFormat.pm:864 - c11 is without format code
2026-11-01 11:23:12 INFO - AmuseWikiFarm.Schema.Result.CustomFormat - /usr/share/perl5/AmuseWikiFarm/Schema/Result/CustomFormat.pm:864 - c12 is without format code

pdf for t1 is disabled 这类 INFO 是站点输出开关(site 表 pdf/sl_pdf 等字段)生效的正常记录;排查"为什么没生成 PDF"时先看这里。

五、注意事项

  1. 保留变量不可 CLI 修改:set-site-variable 对 mode/id/last_updated 会先打印 Updating ... 再 die 回滚(源码 %reserved = (id => 1, mode => 1, last_updated => 1)),别被第一行输出骗了——详见 6.1。
  2. --help 有副作用的命令:generate-meta-config 与 populate-webfonts 的 --help 直接执行生成/检查动作而非打印帮助;reset-password 与 import-redirections 根本不支持 --help(die)。探边界优先用裸跑(打印 Usage)或手册页。
  3. clone-site import 不搬文本树:只建配置,repo 目录需自己放置(实测提示行见 4.4)。
  4. check-compiler 的 exit 255 不等于编译挂了:前两项 ok + * Created *.pdf 即链路正常(见 6.3)。
  5. generate-nginx-conf 不自动生效:它只打印 root 手工三步,覆盖前务必 diff -Nu 目检。
  6. 身份与目录:root 用 /usr/sbin/amusewiki 包装器最省事;直接以 amusewiki 用户操作时务必在 /var/lib/amusewiki 下跑 /usr/bin/amusewiki-*(amusewiki shell 是进入该用户的最短路径)。
  7. 手册页后缀是 .1p:Perl 脚本装到 man1p 节,man amusewiki-clone-site 可直接读。

六、常见问题

6.1 set-site-variable --set mode=public 不生效

现象:CLI 把 demo 站点改公开,第一行明明打印了 Updating demo mode => public,curl 仍是 401:

Updating demo mode => public
GET / (public): 401

查库发现根本没写进去(site 表 mode 仍是 private):

amw|private|0|1
demo|private|0|1

根因:stderr 里藏着 die 与事务回滚(分开跑并保留 stderr 才暴露):

mode is reserved, please use the admin panel at /usr/share/perl5/AmuseWikiFarm/Schema/Result/Site.pm line 4096.
DBIx::Class::Storage::TxnScopeGuard::DESTROY(): A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back. at /usr/share/perl5/AmuseWikiFarm/Schema/Result/Site.pm line 4096

源码 Site.pm 的 update_option_value 定义了保留变量并 die 回滚:

    my %reserved = (id => 1,
                    mode => 1,
                    last_updated => 1);
    die "$option is reserved, please use the admin panel" if $reserved{$option};

即 Updating ... 打印在 die 之前,属于误导性输出;TxnScopeGuard 保证整个写事务回滚。

解法:① 官方推荐走管理面板 /admin/site/... 的站点设置;② 应急可直接改库(SQLite),实测 update site set mode='public' where id='demo' 后:

amw|private
demo|public
GET /library/ (public): 200

公开访问立即恢复 200。部署篇 Q7 若按 CLI 改 mode 会踩此坑,以本节为准。

6.2 export-titles 报 Can't locate Excel/Writer/XLSX.pm

现象:对 demo 导出标题清单,非零退出且无文件产出:

Can't locate Excel/Writer/XLSX.pm in @INC (you may need to install the Excel::Writer::XLSX module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.36.0 /usr/local/share/perl/5.36.0 /usr/lib/x86_64-linux-gnu/perl5/5.36 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.36 /usr/share/perl/5.36 /usr/local/lib/site_perl) at /usr/bin/amusewiki-export-titles line 41.
exit=2

根因:Excel::Writer::XLSX 模块不在依赖里;且脚本 --help 给的 Debian 包名 "libspreadsheet-xlsx-perl" 是错的——那是读 XLSX 的库,写 XLSX 的是 libexcel-writer-xlsx-perl。

解法(实测 apt 安装):

Selecting previously unselected package libexcel-writer-xlsx-perl.
Preparing to unpack .../libexcel-writer-xlsx-perl_1.10-1_all.deb ...
Unpacking libexcel-writer-xlsx-perl (1.10-1) ...
Setting up libexcel-writer-xlsx-perl (1.10-1) ...

重跑即成功:

exit=0
/tmp/titles.xlsx: Microsoft Excel 2007+
-rw-r--r-- 1 amusewiki amusewiki 5831 Nov  1 11:20 /tmp/titles.xlsx

6.3 check-compiler 报 Command 'xelatex' not found / 前两项 ok 后 exit 255

两个独立问题:

  1. Command 'xelatex' not found:check-compiler 按固定 PATH 列表找 xelatex(报错行原文列出 /usr/local/sbin, /usr/local/bin, /usr/sbin, /usr/bin, /sbin, /bin),而 TeX Live 安装在独立前缀(本环境 amusewiki-texlive,其二进制目录不在上述列表)。amusewiki-jobber.service 的 Environment="PATH=/opt/amusewiki-texlive/current/bin/arch:/usr/local/bin:/usr/bin:/bin" 就是为此——手工跑时把该目录加进 PATH 即可,实测加 PATH 后 * Created tl.pdf、ok 1/ok 2 通过。
  2. exit 255:即使 PDF 编译成功,脚本继续做"从 tex 正文探测语言"的后续测试时 die:Couldn't find the language in the tex body at /usr/bin/amusewiki-check-compiler line 61.(# Looks like your test exited with 255 just after 2.)。这是该自检脚本自身的缺陷,判读以 * Created *.pdf 与 ok 1/ok 2 为准,不必被 255 吓到;真正的链路故障看第 1 条的报错形态。

七、参考链接

AmuseWiki 2.611 常用 CLI 命令与工具详解 - Quzuo