Rukovoditel 3.7.3 常用 CLI 与运维命令详解

Rukovoditel 3.7.3 运维命令手册:17 个 cron 脚本实测、/etc/cron.d 配置与两个真实坑、mysqldump 与自带 zip 备份恢复闭环、覆盖升级与回滚、权限与日志排障。

RukovoditelRukovoditelPHP 应用2026/10/28

Rukovoditel 3.7.3 常用 CLI 与运维命令详解

目标:给出 Rukovoditel 3.7.3 日常运维的完整命令手册——定时任务(cron)脚本体系、备份与恢复、升级覆盖、权限修复、日志排查。Rukovoditel 无独立 CLI 工具链,本文以系统命令与应用自带脚本为骨架,全部命令与回显均在 Ubuntu 22.04.5 LTS 实机逐条验证。

一、环境信息

本文实测环境沿用同系列安装篇部署结果:

项目值
操作系统Ubuntu 22.04.5 LTS(x86_64)
应用版本Rukovoditel 3.7.3
Web 栈Nginx 1.18.0 + PHP-FPM 8.1.2-1ubuntu2.28 + MariaDB 10.6.23
应用目录/var/www/rukovoditel
数据库库名/账号 rukovoditel,密码 q1w2e3r4
cron 服务systemd 管理(cron.service,Ubuntu 22.04 官方仓库 cron 包)
管理员账号admin / q1w2e3r4

安装部署见《Rukovoditel 3.7.3 Ubuntu 22.04 安装指南》,配置体系见《Rukovoditel 3.7.3 配置参数详解》。

二、前置条件

运维命令均需具备以下条件:

  1. root 或 sudo 权限(操作 systemd 服务、/etc/cron.d、应用目录);
  2. 数据库专用账号可用(验证命令见下);
  3. PHP CLI 可用(cron 脚本通过 php 命令执行)。

逐项验证:

php -v | head -1
mysql -urukovoditel -pq1w2e3r4 -e "SELECT VERSION();" | tail -1
systemctl is-active nginx; systemctl is-active php8.1-fpm; systemctl is-active mariadb

实测回显:

PHP 8.1.2-1ubuntu2.28 (cli) (built: Oct 19 2026 18:54:45) (NTS)
10.6.23-MariaDB
active
active
active

三、运维工具概览

Rukovoditel 3.7.3 没有独立的 CLI 工具链(无 artisan/console 式命令行程序,无自研 CLI 二进制)。它的「命令行面」由两部分构成:

类别位置说明
应用定时任务脚本/var/www/rukovoditel/cron/*.php17 个 PHP 脚本,负责邮件、备份、通知等后台动作,依赖系统 cron 调度
系统运维命令mysqldump / mysql / systemctl / unzip / chown 等备份、恢复、升级、权限、日志的标准 Linux 手段

💡 技术拓展:PHP 应用的后台任务调度常见三种模式——应用内嵌调度器(如 WordPress 的 wp-cron,靠访问触发,流量小会漏跑)、系统 cron 直接调脚本(如 Rukovoditel 的 cron/ 目录,最传统可靠)、常驻队列进程(如 Laravel Horizon,功能强但多一个守护进程要管)。Rukovoditel 采用第二种:系统 cron 每分钟级触发 PHP 脚本,优点是零额外进程、失败可查 syslog,缺点是调度粒度受 cron 表达式限制(最小 1 分钟)。

四、定时任务脚本(cron/)详解

4.1 脚本清单与官方分发内容

应用自带 17 个 cron 脚本(实测目录列表):

ls /var/www/rukovoditel/cron/

实测回显:

autostatus.php
backup.php
calendar.php
chat.php
currencies.php
email.php
email_by_date.php
email_fetch.php
email_notification.php
file_storage.php
notification.php
process.php
recurring_tasks.php
sms_by_date.php
sms_by_hour.php
xls_import.php
xml_import.php

各脚本职责(按脚本头部与后台功能对应关系归纳):

脚本职责免费版主包可运行
email.php发送待发邮件队列(SMTP 投递)✅
notification.php应用内通知汇总✅
backup.php按后台备份设置生成自动备份✅
autostatus.php用户自动离线状态维护✅
calendar.php日历提醒(Extension)❌ 需 ext
chat.php在线聊天轮询(Extension)❌ 需 ext
currencies.php汇率抓取(Extension)❌ 需 ext
email_by_date.php按日期规则发邮件(Extension)❌ 需 ext
email_fetch.phpIMAP 收信(Extension)❌ 需 ext
email_notification.php邮件通知规则(Extension)❌ 需 ext
file_storage.php文件存储队列(Extension)❌ 需 ext
recurring_tasks.php周期任务生成(Extension)❌ 需 ext
sms_by_date.php / sms_by_hour.php短信提醒(Extension)❌ 需 ext
xls_import.php / xml_import.php批量导入处理(CLI 触发时依赖 Web 上下文)⚠️ 报 Warning

4.2 逐个实测脚本运行结果

免费主包环境下逐个执行(cd /var/www/rukovoditel && php cron/<脚本>),实测输出汇总:

php cron/email.php; echo "EXIT=$?"
php cron/notification.php; echo "EXIT=$?"
php cron/backup.php; echo "EXIT=$?"
php cron/autostatus.php; echo "EXIT=$?"

实测回显(四个脚本全部静默成功,退出码 0,无输出即正常——它们把动作写入数据库而非打印):

EXIT=0
EXIT=0
EXIT=0
EXIT=0

依赖 Extension 的脚本实测会报类缺失(免费包内 plugins/ 目录为空,ext 插件不存在),以 currencies.php 与 calendar.php 为例:

php cron/currencies.php; php cron/calendar.php

实测回显(节选):

PHP Fatal error:  Uncaught Error: Class "currencies" not found in /var/www/rukovoditel/cron/currencies.php:35
PHP Fatal error:  Uncaught Error: Class "calendar_notification" not found in /var/www/rukovoditel/cron/calendar.php:38

⚠️ 注意:免费版部署时不要把依赖 Extension 的脚本加进 cron——它们每次执行都会抛 Fatal error 并在日志里堆积报错。只有安装了官方付费 Extension(代码放入 plugins/ext/)后,对应脚本才应纳入调度。

特殊行为的两个脚本实测:

php cron/process.php; echo "EXIT=$?"
php cron/xls_import.php 2>&1 | head -2

实测回显:

Error: process_id is not passed!EXIT=0
PHP Warning:  Undefined array key "REQUEST_URI" in /var/www/rukovoditel/includes/functions/database.php on line 116

解读:process.php 是「由后台配置的流程动作」触发器,必须带 process_id 参数(在后台业务流程里配置后由应用生成带参调用),裸跑必然报参数缺失;xls_import.php/xml_import.php 是 Web 端批量导入的执行入口,CLI 直接运行会报 REQUEST_URI 未定义的 Warning(它依赖 Web 请求上下文),不应放入系统 cron。

4.3 配置系统 cron(实测含两个坑)

以「每分钟跑 email.php」为例的推荐配置。使用 /etc/cron.d/ 系统级文件(格式带用户字段):

cat > /etc/cron.d/rukovoditel << 'EOF'
* * * * * www-data cd /var/www/rukovoditel && /usr/bin/php cron/email.php >> /var/www/rukovoditel/log/rukovoditel-cron.log 2>&1
EOF
chmod 644 /etc/cron.d/rukovoditel
systemctl restart cron

(systemctl restart cron 无输出即为成功;验证:)

systemctl is-active cron
crontab -l 2>/dev/null || echo "root无用户级crontab(本文用/etc/cron.d/)"

实测回显:

active
root无用户级crontab(本文用/etc/cron.d/)

等待下一个整分钟触发后查看调度与执行记录:

journalctl -u cron --no-pager -n 3 | grep CMD
ls -la /var/www/rukovoditel/log/rukovoditel-cron.log

实测回显:

Oct 28 01:30:01 rukovoditel-lab CRON[17757]: (www-data) CMD (cd /var/www/rukovoditel && /usr/bin/php cron/email.php >> /var/www/rukovoditel/log/rukovoditel-cron.log 2>&1)
-rw-rw-r-- 1 www-data www-data 0 Oct 28 01:30 /var/www/rukovoditel/log/rukovoditel-cron.log

(日志 0 字节即 email.php 静默成功;有邮件待发时日志里会出现 SMTP 交互或错误信息。)

排障实录(本文实测遇到的两个坑,读者照避):

  1. 坑一:用户级 crontab 不认用户字段。本文最初把 * * * * * www-data cd ... 写进 root 的用户级 crontab(crontab -e),结果 cron 把 www-data 当命令执行,journalctl 出现 (root) CMD (www-data cd ...) 且应用脚本从未运行。原因:/etc/crontab 与 /etc/cron.d/* 是系统级格式(第一字段为用户名),而用户级 crontab 没有 user 字段。解决:改用 /etc/cron.d/rukovoditel(见上文),journalctl 确认 (www-data) CMD (...) 生效。
  2. 坑二:www-data 无权写 /var/log。配置里把输出重定向到 /var/log/rukovoditel-cron.log 时,任务实际以 www-data 运行、对 /var/log 无写权限,日志文件创建失败(实测 ls /var/log/rukovoditel-cron.log 报 No such file)。解决:日志落到应用自带且属主为 www-data 的 log/ 目录(/var/www/rukovoditel/log/),实测文件成功生成。

生产推荐 cron 配置(免费版常用三件套,注释说明频率取舍):

cat > /etc/cron.d/rukovoditel << 'EOF'
# 邮件投递:每分钟,保证通知及时
* * * * * www-data cd /var/www/rukovoditel && /usr/bin/php cron/email.php >> /var/www/rukovoditel/log/rukovoditel-cron.log 2>&1
# 应用内通知:每 5 分钟
*/5 * * * * www-data cd /var/www/rukovoditel && /usr/bin/php cron/notification.php >> /var/www/rukovoditel/log/rukovoditel-cron.log 2>&1
# 自动备份:每天 02:30(时间避开业务高峰)
30 2 * * * www-data cd /var/www/rukovoditel && /usr/bin/php cron/backup.php >> /var/www/rukovoditel/log/rukovoditel-cron.log 2>&1
EOF
chmod 644 /etc/cron.d/rukovoditel
systemctl restart cron

实测回显:无输出(配置成功);验证方式同上文 journalctl + 日志文件。

五、备份与恢复运维命令

5.1 mysqldump 全库备份(推荐主用)

Rukovoditel 的全部业务数据在一个 MySQL 库里(应用配置也在库中 app_configuration 表),mysqldump 是最直接的备份手段:

mysqldump -urukovoditel -pq1w2e3r4 rukovoditel > /tmp/rukovoditel_backup.sql
ls -la /tmp/rukovoditel_backup.sql
grep -c "CREATE TABLE" /tmp/rukovoditel_backup.sql

实测回显:

-rw-r--r-- 1 root root 99912 Oct 28 01:11 /tmp/rukovoditel_backup.sql
84

(84 张表与安装篇安装后的建表数量一致;刚安装的空库备份约 100KB,业务数据增长后体积随之增长。)

附件与备份目录是文件数据,SQL 备份不含它们,需一并打包:

tar -czf /tmp/rukovoditel_files_$(date +%F).tar.gz -C /var/www/rukovoditel uploads backups
ls -la /tmp/rukovoditel_files_*.tar.gz

实测回显(刚安装环境无附件,包很小):

-rw-r--r-- 1 root root 394 Oct 28 01:35 /tmp/rukovoditel_files_2026-10-28.tar.gz

5.2 应用自带备份(backup.php / 后台备份)

应用内置备份能力由 cron/backup.php(系统 cron 触发)与后台备份设置共同工作,产物落在 backups/auto/ 目录:

cd /var/www/rukovoditel && php cron/backup.php; echo "EXIT=$?"
ls -la backups/auto/

实测回显:

EXIT=0
总用量 16
drwxr-xr-x  2 www-data www-data 4096 Oct 28 01:11 auto
-rw-r--r--  1 root     root     7719 Oct 28 01:11 autobackup_2026-10-28_09-11_Rukovoditel_3.7.3.sql.zip

产物解读:文件名格式 autobackup_<月-日>_<时分>_Rukovoditel_<版本>.sql.zip,其中时间 09-11 为应用时区(CFG_APP_TIMEZONE=Asia/Shanghai)下的时刻,对应服务器 UTC 的 01:11。内容为 zip 压缩的 SQL(解压后 63235 字节,文件头带 #Rukovoditel 3.7.3; 版本标识与逐表 DROP TABLE IF EXISTS 语句,共 84 个 CREATE TABLE)。

备份保留策略:在后台 Configuration → Application 页配置备份相关项后由 backup.php 按计划清理;磁盘紧张时应把 backups/ 目录纳入监控。

5.3 恢复闭环实测

方式一:mysqldump 备份恢复(DROP 库重建后导入):

mysql -urukovoditel -pq1w2e3r4 -e "DROP DATABASE rukovoditel; CREATE DATABASE rukovoditel CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -urukovoditel -pq1w2e3r4 rukovoditel < /tmp/rukovoditel_backup.sql
mysql -urukovoditel -pq1w2e3r4 rukovoditel -e "SELECT COUNT(*) AS tables_cnt FROM information_schema.tables WHERE table_schema='rukovoditel'; SELECT field_12 FROM app_entity_1;"
curl -s -o /dev/null -w "恢复后登录页=%{http_code}\n" http://localhost/

实测回显:

tables_cnt
84
field_12
admin
恢复后登录页=302

方式二:应用自带 zip 备份恢复(解压后直接导入,SQL 自带 DROP 语句无需清库):

mysql -urukovoditel -pq1w2e3r4 -e "DROP DATABASE rukovoditel; CREATE DATABASE rukovoditel CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
unzip -o -q /var/www/rukovoditel/backups/auto/autobackup_2026-10-28_09-11_Rukovoditel_3.7.3.sql.zip -d /tmp/zipbk
mysql -urukovoditel -pq1w2e3r4 rukovoditel < /tmp/zipbk/autobackup_2026-10-28_09-11_Rukovoditel_3.7.3.sql
mysql -urukovoditel -pq1w2e3r4 rukovoditel -e "SELECT COUNT(*) AS tables_cnt FROM information_schema.tables WHERE table_schema='rukovoditel'; SELECT field_12 FROM app_entity_1;"

实测回显:

tables_cnt
84
field_12
admin

两种方式均完整恢复业务数据与管理员账号(admin)。恢复后浏览器重新登录即可(会话数据随库恢复或重新生成,无需额外操作)。

六、升级与覆盖运维

6.1 升级路径与机制

Rukovoditel 官网下载页(download.php)始终提供最新版 zip;安装包 install/autoupdate/ 目录内置了历史版本的数据库升级脚本(实测列表节选):

data_prepare_from_1.6_to_1.7.php
data_prepare_from_1.7_to_1.8.php
data_prepare_from_2.6_to_2.7.php
from_1.5_to_1.6.php
from_1.6_to_1.7.php

(输出节选,实测首尾:目录内含自 1.5 起各历史版本的逐级升级脚本,文件名格式统一为 from_旧版_to_新版.php 与 data_prepare_from_旧版_to_新版.php。)

官网还提供版本更新公告页(new_release.php?version=3.7,即 3.7 系列说明)。应用后台默认开启更新检查(配置项 CFG_DISABLE_CHECK_FOR_UPDATES 可关闭,见配置篇 5.6 节)。

6.2 覆盖升级实测流程

覆盖升级的关键是保留 config/database.php 与数据目录。实测以当前版本包重演覆盖流程(升级到未来新版的操作步骤完全一致):

cp /var/www/rukovoditel/config/database.php /tmp/db.php.bak
cd /tmp
wget -q --load-cookies=cookies.txt --keep-session-cookies --save-cookies=cookies.txt "https://www.rukovoditel.net/download.php?action=download" -O rukovoditel-new.zip
unzip -q -o rukovoditel-new.zip -d /var/www/rukovoditel/
ls /var/www/rukovoditel/config/database.php > /dev/null && echo "config保留=OK"
chown -R www-data:www-data /var/www/rukovoditel
curl -s -o /dev/null -w "覆盖后首页=%{http_code}\n" http://localhost/
curl -s -L http://localhost/ | grep -oE "<title>[^<]*" | head -1

实测回显:

config保留=OK
覆盖后首页=302
<title>RK

流程解读与要点:

  • unzip -o 只覆盖同名文件、保留 config/database.php(实测确认未被破坏);为防意外,先备份该文件到 /tmp;
  • 覆盖后必须 chown -R www-data:www-data 归还属主(新解压文件属 root);
  • 若新版包含数据库结构变更,浏览器访问应用会按 install/autoupdate/ 机制提示升级步骤,按页面指引执行即可;
  • 升级前先做 5.1 节备份,升级失败可按 5.3 节恢复。

6.3 回滚

回滚 = 恢复旧版代码 + 恢复旧库:把旧版 zip 解压覆盖(同 6.2 步骤,用旧包),再按 5.3 节把升级前的 mysqldump 备份导回。因此升级前备份是硬性前置。

七、权限与服务管理命令

7.1 权限修复

应用文件属主必须是 PHP-FPM 运行账号 www-data,误用 root 操作应用目录后统一修复:

chown -R www-data:www-data /var/www/rukovoditel
ls -la /var/www/rukovoditel/config/ | head -5

实测回显(修复后属主正确):

-rw-r--r--  1 www-data www-data  315 Dec 10  2018 database_example.php
-rw-r--r--  1 www-data www-data  143 Oct 28 01:36 database.php
-rw-r--r--  1 www-data www-data 2917 Jul 10  2025 server.php

需保持 www-data 可写的目录(实测权限形态):

ls -ld /var/www/rukovoditel/uploads /var/www/rukovoditel/backups /var/www/rukovoditel/tmp /var/www/rukovoditel/cache /var/www/rukovoditel/log

实测回显:

drwxr-xr-x 2 www-data www-data 4096 Feb 16  2026 /var/www/rukovoditel/uploads
drwxr-xr-x 3 www-data www-data 4096 Feb 16  2026 /var/www/rukovoditel/backups
drwxr-xr-x 2 www-data www-data 4096 Feb 16  2026 /var/www/rukovoditel/tmp
drwxr-xr-x 2 www-data www-data 4096 Feb 16  2026 /var/www/rukovoditel/cache
drwxrwxrwx 4 www-data www-data 4096 Oct 28 01:30 /var/www/rukovoditel/log

7.2 服务管理(systemctl,每行一个单元)

systemctl restart nginx
systemctl restart php8.1-fpm
systemctl restart mariadb
systemctl restart cron

状态确认:

systemctl is-active nginx; systemctl is-active php8.1-fpm; systemctl is-active mariadb; systemctl is-active cron

实测回显(四行):

active
active
active
active

⚠️ 注意:重启 php8.1-fpm 会断开所有在线用户请求(页面短暂 5xx/重连),生产操作安排在低峰期;单纯改 php.ini 用 systemctl reload php8.1-fpm 即可平滑生效。

八、日志查看与排障

各组件日志位置汇总(实测确认路径):

组件日志路径查看命令
Nginx 访问/错误/var/log/nginx/access.log、error.logtail -f /var/log/nginx/error.log
Apache 站点(B 方案)/var/log/apache2/rukovoditel_error.logtail -f /var/log/apache2/rukovoditel_error.log
PHP-FPM/var/log/php8.1-fpm/tail -f /var/log/php8.1-fpm/log
cron 调度记录journal(无 syslog 的环境)journalctl -u cron --no-pager -n 20
应用 cron 输出/var/www/rukovoditel/log/rukovoditel-cron.logtail -f /var/www/rukovoditel/log/rukovoditel-cron.log
应用备份产物/var/www/rukovoditel/backups/auto/ls -la backups/auto/

排障命令实测示例:

journalctl -u cron --no-pager -n 4 | grep -E "CMD|info"
tail -3 /var/log/nginx/error.log

实测回显:

Oct 28 01:28:01 rukovoditel-lab CRON[17700]: (root) CMD (www-data cd /var/www/rukovoditel && /usr/bin/php cron/email.php >> /var/log/rukovoditel-cron.log 2>&1)
Oct 28 01:28:01 rukovoditel-lab CRON[17699]: (CRON) info (No MTA installed, discarding output)
Oct 28 01:30:01 rukovoditel-lab CRON[17757]: (www-data) CMD (cd /var/www/rukovoditel && /usr/bin/php cron/email.php >> /var/www/rukovoditel/log/rukovoditel-cron.log 2>&1)

(nginx error.log 在配置正确、无异常请求时为空文件,tail 无输出属正常。)

解读第三行前两行的对照:01:28 的 (root) CMD (www-data ...) 是坑一现场(用户级 crontab 误用用户字段),01:30 的 (www-data) CMD (...) 是 /etc/cron.d/ 修复后的正确形态——排障时先看 (用户) CMD (...) 里用户与命令是否匹配预期。

九、注意事项

  1. Extension 脚本勿入 cron:calendar/chat/sms/recurring_tasks 等脚本在免费包下必然 Fatal error(实测见 4.2 节),装了付费扩展后才启用;
  2. 备份双轨:mysqldump 保数据库 + tar 保 uploads/backups 目录,两者都做才能完整恢复(SQL 备份不含附件文件);
  3. 升级前必须备份:6.3 节回滚依赖 5.1 节的升级前备份,没有备份就没有回滚;
  4. config/database.php 是升级覆盖的唯一幸存者:覆盖解压保留它,但手工「删目录重解压」会丢,务必先备份;
  5. 密码修改走后台:管理员密码在后台用户资料中修改(数据库存储的是 PasswordHash 哈希,不要手工改库);
  6. cron 频率权衡:email.php 每分钟跑对 50 人以内团队压力可忽略;数据量大后观察 php 进程峰值再降频。

十、常见问题(FAQ)

Q1:cron 配好了但邮件一直不发? 按序排查:① journalctl -u cron | grep CMD 确认任务被调度且用户正确(www-data 而非 root);② 手工执行 sudo -u www-data php cron/email.php 看报错(实测环境 sudo 未装时用 su -s /bin/bash www-data -c 'php cron/email.php');③ 后台确认 CFG_EMAIL_USE_SMTP=1 且 SMTP 参数正确(配置篇 5.7 节实测保存方法);④ 后台 Configuration → Emails Send Test 发测试邮件观察日志。

Q2:journalctl 报 "No MTA installed, discarding output"? 这是 cron 尝试把任务输出以邮件形式投递但系统没装 MTA(实测环境回显见第八节)。如果重定向已写日志文件(>> ... 2>&1)此提示无害;想消除则 apt-get install -y postfix 或确保每条任务都重定向了输出。

Q3:备份文件 0 字节或备份脚本跑完没产物? backup.php 静默成功时立即检查 backups/auto/ 目录时间戳(实测正常产物形如 autobackup_2026-10-28_09-11_Rukovoditel_3.7.3.sql.zip);没有产物通常是后台备份配置未启用或数据库账号权限变化,用 5.1 节 mysqldump 命令交叉验证数据库可用性。

Q4:恢复备份后登录不上? 确认三件事:① 导入的是恢复目标版本一致的备份(zip 备份文件名带版本号,跨大版本恢复需按官方升级脚本对齐);② config/database.php 指向的库就是刚导入的库;③ 浏览器清 cookie 重登(旧会话 id 已随 DROP 库失效)。

Q5:磁盘被 backups/ 撑满怎么办? 立即动作:清理历史 zip(ls -la backups/auto/ 按时间删旧),随后在后台配置自动备份保留策略;长期方案是把 backups/ 指向独立分区或由系统级脚本定期搬移到备份存储(改 server.php 的 DIR_FS_BACKUPS_AUTO 常量,见配置篇 5.2 节)。

十一、参考链接