FreeScout 常用 CLI 命令详解

FreeScout 1.8.248 的 artisan 命令行工具集实测详解:以 php artisan list 实际输出为准梳理 137 条命令全景,freescout:* 应用命令 23 条、数据库迁移、队列与调度、缓存配置、模块管理逐条讲解并附真实回显,沉淀 --stop-when-empty 报错、tinker HOME 修正、clean-tmp 权限提示等排障实录。

FreeScout工单系统邮件服务器2026/10/21

FreeScout 常用 CLI 命令详解

目标:系统梳理开源帮助台 FreeScout 1.8.248 的命令行(artisan)工具集——以 php artisan list 实际输出为准逐条讲解 freescout:* 应用命令、数据库迁移、队列与调度、缓存与配置、模块管理五大类命令的用法、参数与真实回显,并沉淀实测中的报错与排障过程,供日常运维与升级操作直接照做。已在 Ubuntu 22.04 LTS 服务器(安装流程见 《Ubuntu 22.04 安装 FreeScout 1.8.248 指南》)上逐条实测通过。

一、环境信息

本章记录命令实测所用服务器的软硬件环境与软件版本,本文所有命令与回显均来自该环境,供读者对照复现。

实测环境:

  • 操作系统:Ubuntu 22.04.5 LTS(GNU/Linux x86_64)
  • 配置:12 vCPU / 32 GB 内存 / 普通云盘
  • 网络:可直连公网(GitHub、Ubuntu 归档),无出站代理

实测软件版本清单:

组件实测版本说明
FreeScout1.8.248GitHub 1.8.248 标签(dist 形态),安装路径 /var/www/html
Laravel Framework5.5.40(项目自维护定制 fork)php artisan --version 实测输出
PHP8.3.35(fpm + cli)ppa:ondrej/php
Nginx1.18.0 (Ubuntu)Ubuntu 22.04 官方仓库
MariaDB10.6.23-MariaDBUbuntu 22.04 官方仓库
Psy Shell(tinker)v0.9.12php artisan tinker 启动横幅实测

其他关键信息:

  • 访问地址:http://192.168.146.128:8155(.env 中 APP_URL 同值)
  • 管理员账号:admin@freescout.local / q1w2e3r4(安装篇 5.7 节创建,id: 1)
  • 应用运行身份:www-data(Nginx 与 PHP-FPM 统一该用户)
  • 定时任务:www-data 的 crontab 每分钟执行 schedule:run(见 6.6 节)

版本时效说明:2026-10-21 经 GitHub Releases(https://github.com/freescout-help-desk/freescout/releases.atom)复查,上游最新稳定版仍为 1.8.248(2026-10-17 发布),与 《FreeScout 1.8.248 介绍与选型指南》定稿时的基准一致,本文全部实测基于该版本。FreeScout 发布节奏较快,阅读本文时若上游已出新版,请先 git fetch --tags 并切到对应标签后再按本文核对命令行为。

二、工具概览

本章先建立 FreeScout 命令行的整体认知:入口是什么、命令有多少、按什么分类,再进入后续逐条详解。FreeScout 基于 Laravel Framework 5.5.40 定制 fork 开发,因此它的 CLI 就是 Laravel 的 artisan 控制台——入口文件为应用根目录下的 artisan 脚本,全部命令通过 php artisan <命令> 形式调用。除 Laravel 框架自带命令外,FreeScout 在 app/Console/Commands/ 下注册了 freescout: 前缀的应用专属命令,并引入了 nwidart/laravel-modules 模块系统(module:* 命令族)与翻译管理(translations:*)等第三方扩展命令。

查看全部命令用 php artisan list。实测(在应用根目录执行):

cd /var/www/html
sudo -u www-data php artisan list

实测输出(1.8.248 全量,共 137 条命令,逐字照抄):

Laravel Framework 5.5.40

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  clear-compiled                       Remove the compiled class file
  down                                 Put the application into maintenance mode
  env                                  Display the current framework environment
  help                                 Displays help for a command
  inspire                              Display an inspiring quote
  list                                 Lists commands
  migrate                              Run the database migrations
  optimize                             Optimize the framework for better performance (deprecated)
  preset                               Swap the front-end scaffolding for the application
  serve                                Serve the application on the PHP development server
  tinker                               Interact with your application
  up                                   Bring the application out of maintenance mode
 activitylog
  activitylog:clean                    Clean up old records from the activity log.
 app
  app:name                             Set the application namespace
 auth
  auth:clear-resets                    Flush expired password reset tokens
 cache
  cache:clear                          Flush the application cache
  cache:forget                         Remove an item from the cache
  cache:table                          Create a migration for the cache database table
 config
  config:cache                         Create a cache file for faster configuration loading
  config:clear                         Remove the configuration cache file
 db
  db:seed                              Seed the database with records
 event
  event:generate                       Generate the missing events and listeners based on registration
 freescout
  freescout:after-app-update           Run commands after application has been updated
  freescout:build                      Run commands building application assets
  freescout:check-conv-viewers         Check if user finished viewing conversation
  freescout:check-requirements         Check console version of PHP
  freescout:clean-notifications-table  Delete old read records from notifications table.
  freescout:clean-send-log             Delete old records from send log.
  freescout:clean-tmp                  Remove from system temp folder old FreeScout tempt files to avoid "No space left on device"
  freescout:clear-cache                Clear application cache and cache config
  freescout:create-user                Create a new user
  freescout:fetch-emails               Fetch emails from mailboxes addresses
  freescout:fetch-monitor              Check emails fetching and send alert if fething is not working or recovered
  freescout:generate-vars              Generates vars.js file with variables and translated string
  freescout:logout-users               Logout all users
  freescout:logs-monitor               Send new log records by email
  freescout:module-build               Build module or all modules (if module_alias is empty)
  freescout:module-check-licenses      Check licenses for modules
  freescout:module-install             Install module or all modules (if module_alias is empty): run migrations and create a symlink
  freescout:module-laroute             Generate a laravel routes JS-file for a module or all modules (if module_alias is empty)
  freescout:module-update              Update all modules or a single module (if module_alias is set)
  freescout:parse-eml                  Parse EML file
  freescout:send-monitor               Check if queue:work is processing emails queue and show an alert in the web interface if needed
  freescout:update                     Update application to the latest version from GitHub
  freescout:update-folder-counters     Update counters for all folders
 key
  key:generate                         Set the application key
 laroute
  laroute:generate                     Generate a laravel routes file
 make
  make:auth                            Scaffold basic login and registration views and routes
  make:command                         Create a new Artisan command
  make:controller                      Create a new controller class
  make:event                           Create a new event class
  make:exception                       Create a new custom exception class
  make:factory                         Create a new model factory
  make:job                             Create a new job class
  make:listener                        Create a new event listener class
  make:mail                            Create a new email class
  make:middleware                      Create a new middleware class
  make:migration                       Create a new migration file
  make:model                           Create a new Eloquent model class
  make:notification                    Create a new notification class
  make:policy                          Create a new policy class
  make:provider                        Create a new service provider class
  make:request                         Create a new form request class
  make:resource                        Create a new resource
  make:rule                            Create a new validation rule
  make:seeder                          Create a new seeder class
  make:test                            Create a new test class
 migrate
  migrate:fresh                        Drop all tables and re-run all migrations
  migrate:install                      Create the migration repository
  migrate:refresh                      Reset and re-run all migrations
  migrate:reset                        Rollback all database migrations
  migrate:rollback                     Rollback the last database migration
  migrate:status                       Show the status of each migration
 module
  module:disable                       Disable the specified module.
  module:dump                          Dump-autoload the specified module or for all module.
  module:enable                        Enable the specified module.
  module:install                       Install the specified module by given package name (vendor/name).
  module:list                          Show list of all modules.
  module:make                          Create a new module.
  module:make-command                  Generate new Artisan command for the specified module.
  module:make-controller               Generate new restful controller for the specified module.
  module:event                         Create a new event class for the specified module
  module:make-factory                  Create a new model factory for the specified module.
  module:make-job                      Create a new job class for the specified module
  module:make-listener                 Create a new event listener class for the specified module
  module:make-mail                     Create a new email class for the specified module
  module:make-middleware               Create a new middleware class for the specified module.
  module:make-migration                Create a new migration for the specified module.
  module:make-model                    Create a new model for the specified module.
  module:make-notification             Create a new notification class for the specified module.
  module:make-policy                   Create a new policy class for the specified module.
  module:make-provider                 Create a new service provider for the specified module.
  module:make-request                  Create a new form request class for the specified module.
  module:make-resource                 Create a new resource class for the specified module.
  module:make-rule                     Create a new validation rule for the specified module.
  module:make-seed                     Generate new seeder for the specified module.
  module:make-test                     Create a new test class for the specified module.
  module:migrate                       Migrate the migrations from the specified module or from all modules.
  module:migrate-refresh               Rollback & re-migrate the modules migrations.
  module:migrate-reset                 Reset the modules migrations.
  module:migrate-rollback              Rollback the modules migrations.
  module:migrate-status                Status for all module migrations
  module:publish                       Publish a module's assets to the application
  module:publish-config                Publish a module's config files to the application
  module:publish-migration             Publish a module's migrations to the application
  module:publish-translation           Publish a module's translations to the application
  module:route-provider                Create a new route service provider for the specified module.
  module:seed                          Run database seeder from the specified module or from all modules.
  module:setup                         Setting up modules folders for first use.
  module:unuse                         Forget the used module with module:use
  module:update                        Update dependencies for the specified module or for all modules.
  module:use                           Use the specified module.
 notifications
  notifications:table                  Create a migration for the notifications table
 package
  package:discover                     Rebuild the cached package manifest
 queue
  queue:failed                         List all of the failed queue jobs
  queue:failed-table                   Create a migration for the failed queue jobs database table
  queue:flush                          Flush all of the failed queue jobs
  queue:forget                         Delete a failed queue job
  queue:listen                         Listen to a given queue
  queue:restart                        Restart queue worker daemons after their current job
  queue:retry                          Retry a failed queue job
  queue:table                          Create a migration for the queue jobs database table
  queue:work                           Start processing jobs on the queue as a daemon
 route
  route:cache                          Create a route cache file for faster route registration
  route:clear                          Remove the route cache file
  route:list                           List all registered routes
 schedule
  schedule:run                         Run the scheduled commands
 session
  session:table                        Create a migration for the session database table
 storage
  storage:link                         Create a symbolic link from "public/storage" to "storage/app/public"
 translations
  translations:clean                   Clean empty translations
  translations:export                  Export translations to PHP files
  translations:find                    Find translations in php/twig files
  translations:import                  Import translations from the PHP sources
  translations:reset                   Delete all translations from the database
 updater
  updater:check-for-update             Check if a new update is available.
 vendor
  vendor:publish                       Publish any publishable assets from vendor packages
 view
  view:clear                           Clear all compiled view files

💡 说明:上面清单中每个不带冒号的行(如 activitylog、 freescout、 queue)是命令的命名空间分组标题,其下缩进行才是可执行命令;本文实测环境无任何第三方模块,module:* 组为模块系统自带命令,全部可用但多数只在装了模块后才有实际对象(见第八章)。

按功能把 137 条命令归类,运维高频族如下表:

命令族数量作用域本文对应章节
freescout:*23FreeScout 应用专属(用户/邮件/缓存/清理/监控/模块/升级)第四章
migrate*7数据库迁移(含 migrate 主命令)第五章
queue:*9邮件队列与异步任务第六章
schedule:run1定时调度入口(cron 调用它)第六章
cache:* / config:* / route:* / view:clear10缓存与配置维护第七章
module:*30模块系统(nwidart/laravel-modules)第八章
make:* 及其他辅助约 57框架辅助与二次开发第九章

任何一条命令的参数都可用两种方式查看(实测等价):

sudo -u www-data php artisan help freescout:fetch-emails
sudo -u www-data php artisan freescout:fetch-emails --help

两条命令都会输出该命令的 Usage、Arguments、Options 与 Help 描述;本文各节的「参数表」即来自 php artisan help <命令> 的实测输出。

freescout:* 命名空间 23 条命令一览(分组按用途,编号即详解小节):

命令用途详解
freescout:check-requirements检查命令行 PHP 版本与必需扩展/函数4.1
freescout:create-user创建用户(可指定角色/姓名/邮箱/密码)4.2
freescout:logout-users登出全部用户(清空会话)4.3
freescout:fetch-emails从已配置的邮箱抓取来信转为工单4.4
freescout:parse-eml解析 EML 文件(调试邮件解析)4.5
freescout:clear-cache清应用缓存并重建配置缓存(FreeScout 定制)4.6
freescout:generate-vars生成前端变量文件 vars.js4.7
freescout:build生成全部前端资源(vars + laroute 路由)4.7
freescout:update-folder-counters重算全部文件夹的工单计数4.8
freescout:clean-tmp清理系统临时目录中的旧临时文件4.9
freescout:clean-notifications-table删除通知表中旧的已读记录4.9
freescout:clean-send-log删除发送日志中的旧记录4.9
freescout:fetch-monitor检查邮件抓取是否中断并告警4.10
freescout:send-monitor检查邮件队列是否卡死并告警4.10
freescout:logs-monitor把新日志记录发邮件通知4.10
freescout:check-conv-viewers检查用户是否结束查看会话(释放编辑锁)4.11
freescout:module-build构建模块(或全部模块)4.12
freescout:module-install安装模块(跑迁移 + 建符号链接)4.12
freescout:module-laroute生成模块的路由 JS 文件4.12
freescout:module-update更新全部或单个模块4.12
freescout:module-check-licenses检查模块许可状态4.12
freescout:update从 GitHub 更新应用到最新版4.13
freescout:after-app-update应用更新后的固定收尾命令序列4.13

💡 说明:该命令集覆盖了 FreeScout 日常运维的绝大多数命令行场景——用户管理、邮件抓取诊断、缓存重建、数据清理、升级收尾。个别仅出现在 Web 界面的操作(如邮箱配置、工作流)没有命令行形态,属产品设计而非遗漏。

三、前置条件

本章列明执行本文命令前必须满足的环境条件。命令无法执行时按此逐项排查。

  1. 能登录服务器并有 sudo 权限(本文演示统一用 root 执行 sudo;密码为环境自设,不进文档)。
  2. FreeScout 已完成安装并能登录:安装流程见 《Ubuntu 22.04 安装 FreeScout 1.8.248 指南》;组件定位与架构背景见 《FreeScout 1.8.248 介绍与选型指南》。
  3. 拥有应用目录写权限的运行身份:artisan 会写 storage/、bootstrap/cache/,统一以 www-data 身份执行(sudo -u www-data)。用 root 直接执行会把缓存文件属主改成 root,导致 Web 端写入报错——这是最常见的误操作,务必避免。
  4. 进入应用根目录:artisan 必须在含 artisan 脚本的目录(本文为 /var/www/html)执行,否则报 Could not open input file: artisan。
  5. PHP 命令行可用且版本达标:php -v 应显示 8.3.x(freescout:check-requirements 可一键复核,见 4.1 节)。

验证环境就绪(实测):

cd /var/www/html
sudo -u www-data php artisan --version

实测输出:

Laravel Framework 5.5.40

💡 说明:FreeScout 虽然显示 Laravel Framework 5.5.40,但这是项目自维护的定制 fork(overrides/ 目录覆盖了框架层代码以兼容 PHP 8.x),不代表可用任意 Laravel 5.5 生态工具直接套用。

四、freescout:* 应用命令详解

本章逐条实测 FreeScout 应用专属的 23 条命令。每条给出用途、命令形态、参数说明与实测回显;会破坏数据的命令标注警告,未实跑的命令标注「未实跑」并说明原因。除特别说明外,命令均在 /var/www/html 目录下以 sudo -u www-data 执行。

4.1 freescout:check-requirements(环境自检)

本命令检查命令行 PHP 的版本、必需扩展与函数是否就位,输出逐项 OK 清单,是装机后、升级前、排障时的第一检查点。它检查的是 CLI 侧 PHP(php -v 同源),与 Web 侧 PHP-FPM 是两套 php.ini,因此即使 Web 正常,CLI 缺扩展也会在这里暴露。

sudo -u www-data php artisan freescout:check-requirements

实测输出(1.8.248,全量照抄):

PHP Version
 8.3.35........................ OK
PHP Extensions
 OpenSSL....................... OK
 PDO........................... OK
 Mbstring...................... OK
 Tokenizer..................... OK
 JSON.......................... OK
 XML........................... OK
 GD............................ OK
 fileinfo...................... OK
 ZIP........................... OK
 iconv......................... OK
 cURL.......................... OK
 DOM........................... OK
 libxml........................ OK
 intl.......................... OK
 pcntl (console PHP)........... OK
Functions
 shell_exec (PHP).............. OK
 proc_open (PHP)............... OK
 fpassthru (PHP)............... OK
 symlink (PHP)................. OK
 iconv (PHP)................... OK
 dns_get_record (PHP).......... OK
 inet_pton (PHP)............... OK
 pcntl_signal (console PHP).... OK
 ps (shell).................... OK

要点:清单分三段——版本、扩展、函数;任何一段出现非 OK 项都应先补齐再继续其他操作。注意 pcntl (console PHP) 一项:它只在 CLI 生效(Web 侧通常禁用 pcntl),这正是 FreeScout 队列守护进程所依赖的(见 6.2 节)。

4.2 freescout:create-user(创建用户)

本命令从命令行创建 FreeScout 用户,全部参数可选:不带参数执行会进入交互式问答,带全参数则一步完成。安装后的第一个管理员就是用它创建的(安装篇 5.7 节)。实测创建一个演示用户后再删除,验证回显与身份闭环。

命令形态(实测 help 输出的参数表):

sudo -u www-data php artisan freescout:create-user --role=admin --firstName=Demo --lastName=User --email=demo@freescout.local --password=q1w2e3r4

参数说明(来自 php artisan help freescout:create-user 实测):

参数含义备注
--role用户角色admin(管理员)/user(普通坐席)
--firstName / --lastName名 / 姓登录后显示在工单处理记录中
--email登录邮箱(唯一标识)重复创建会报错
--password登录密码交互模式下会隐藏回显

实测输出:

User created with id: 2

验证用户确实创建(tinker 查询,tinker 用法见 9.1 节):

echo 'echo \App\User::count();' | sudo -u www-data HOME=/var/www/html php artisan tinker

实测输出(节选):

USERS: 2

验证后把演示用户删除,恢复环境(实测):

echo 'echo "DELETED: " . \App\User::where("email", "demo@freescout.local")->delete();' | sudo -u www-data HOME=/var/www/html php artisan tinker

实测输出:

DELETED: 1

⚠️ 注意:该命令只有「创建」没有配套的删除命令;删用户请登录 Web 端「管理 → 用户」操作(保留工单历史归属),或如上用 tinker 谨慎处理。命令行创建的用户同样会进入 Web 用户列表。

4.3 freescout:logout-users(登出全部用户)

本命令删除数据库中的全部会话记录,强制所有在线用户重新登录。典型场景:怀疑会话被劫持、修改了会话安全配置后要求全员重新登录(配置篇实测的 419 会话事故恢复时也用到它)。

sudo -u www-data php artisan freescout:logout-users

实测输出:

Deleted sessions: 8

💡 说明:Deleted sessions: 8 是数据库 sessions 表中的会话行数(含本机多次登录的残留),不一定等于在线人数。命令执行后所有已打开的 FreeScout 页面在下次请求时即被踢回登录页。

4.4 freescout:fetch-emails(抓取邮件)

本命令从已配置的邮箱(Web 端「管理 → 邮箱」)拉取来信并转为工单会话,是 cron 每分钟调度链上的核心命令(见 6.6 节)。参数控制抓取范围与调试行为,实测 help 输出的参数表如下:

参数默认值含义
--days"3"抓取最近 N 天的邮件
--unseen"1"1=只抓未读;0=抓取期内全部
--debug"0"1=输出调试信息
--identifier"dummy"抓取任务标识(cron 调用时自动传随机串防并发)
--mailboxes"0"0=全部邮箱;传邮箱 ID 只抓指定邮箱

实测(本环境尚未配置任何邮箱,输出即「无事可做」的真实形态):

sudo -u www-data php artisan freescout:fetch-emails

实测输出:

[2026-10-21 14:43:08] Fetching UNREAD emails for the last 3 days.
[2026-10-21 14:43:08] Fetching finished

💡 说明:两条输出各带时间戳;配置邮箱后再执行,中间会插入逐邮箱的抓取过程行。--identifier 在 cron 自动调用时是 32 位随机串(见 6.6 节 schedule:run 实测输出中的 --identifier=73907a81d9699ef4112b47bfbf70cf78),手动排障时可传固定值便于在日志中过滤。

⚠️ 注意:邮件抓取长期无进展时,先用 freescout:fetch-monitor 判断是「抓取中断」还是「从未配置」(见 4.10 节实测输出对照)。

4.5 freescout:parse-eml(解析 EML 文件)

本命令把一封 EML 原始邮件文件解析成 FreeScout 内部结构(发件人、主题、正文等),用于排查「邮件进来了但没正确转成工单」类问题。它没有命令行参数:固定读取应用目录下 storage/logs/email.eml 文件,用完即分析的调试定位方式。

实测一:文件不存在时的真实报错(排障素材):

sudo -u www-data php artisan freescout:parse-eml

实测输出:


In ParseEml.php line 63:

  file_get_contents(/var/www/html/storage/logs/email.eml): Failed to open str
  eam: No such file or directory

实测二:构造一封 EML 再执行。先把测试邮件写入目标路径(内容为标准邮件头 + 正文):

printf "From: Alice <alice@example.com>\r\nTo: support@freescout.local\r\nSubject: Test EML parse\r\nDate: Tue, 21 Oct 2026 06:00:00 +0000\r\nMessage-ID: <test-001@example.com>\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nHello FreeScout, this is a test EML body.\r\n" | sudo tee /var/www/html/storage/logs/email.eml >/dev/null

再执行解析:

sudo -u www-data php artisan freescout:parse-eml

实测输出(节选,尾部):

Subject: Test EML parse
Date: Tue, 21 Oct 2026 06:00:00 +0000
Message-ID: <test-001@example.com>
Content-Type: text/plain; charset=UTF-8
From:
{"personal":"Alice","mailbox":"alice","host":"example.com","mail":"alice@example.com","full":"Alice <alice@example.com>"}
Reply-To:
{"personal":"Alice","mailbox":"alice","host":"example.com","mail":"alice@example.com","full":"Alice <alice@example.com>"}
In-Reply-To:

References:
[]
Date:
2026-10-27 06:00:00
Subject:
Test EML parse
Text Body:
Hello FreeScout, this is a test EML body.
HTML Body:

💡 说明:输出分两段——前段是原始邮件头回显,后段(From: 起的 JSON 与分段标签)是解析结果:发件人被拆成 personal/mailbox/host/mail/full 五字段,正文落入 Text Body:。测试文件用完建议删除(sudo rm /var/www/html/storage/logs/email.eml),避免下次调试混淆。

⚠️ 注意:解析结果中的 Date: 行(2026-10-27 06:00:00)与邮件头原值(10 月 21 日)存在偏移,这是解析库对日期头的处理结果,以命令实际输出为准;用它对比「同一封邮件在 Web 端显示的收到时间」可判断时间偏移问题出在解析层还是投递层。

4.6 freescout:clear-cache(清缓存并重建,FreeScout 定制)

本命令是 FreeScout 定制的一站式缓存维护命令,一条命令完成:清编译文件 → 清应用缓存 → 清编译视图 → 清配置缓存 → 重建配置缓存 → 清 JS/CSS 构建产物 → 重新生成 vars.js。日常改完 .env 或代码后执行这一条即可,无需逐个跑 Laravel 原生命令。

sudo -u www-data php artisan freescout:clear-cache

实测输出(全量照抄):

The compiled services & packages files have been removed.
Cache cleared successfully.
Compiled views cleared!
Configuration cache cleared!
Configuration cached successfully!
Cleared: JS and CSS builds
Created: /js/builds/vars.js

参数(实测 help):--doNotCacheConfig 跳过配置缓存重建、--doNotGenerateVars 跳过 vars.js 生成,两个都不常用。

💡 说明:注意第 5 行 Configuration cached successfully!——FreeScout 在清理后会主动重建配置缓存,这一点与 Laravel 原生 config:clear(只清不建)不同。配置缓存的生效机制与排查方法(改了 .env 不生效类问题)见 《FreeScout 1.8.248 配置参数详解》第三章。

⚠️ 注意:执行本命令会短暂清空所有在线用户的会话相关缓存,属正常现象;升级 FreeScout 后官方也要求执行它(或直接跑 4.13 的 freescout:after-app-update)。

4.7 freescout:generate-vars 与 freescout:build(前端资源生成)

这两条命令负责生成前端 JS 资源。freescout:generate-vars 把应用变量与翻译字符串写入 public/js/builds/vars.js;freescout:build 在此基础上再生成 laroute 路由文件,等价于「generate-vars + laroute:generate」组合(源码即两次 $this->call())。改了翻译或升级后前端出现异常时执行。

实测 freescout:generate-vars:

sudo -u www-data php artisan freescout:generate-vars

实测输出:

Created: /js/builds/vars.js

实测 freescout:build:

sudo -u www-data php artisan freescout:build

实测输出:

Created: /js/builds/vars.js
Created: public/js/laroute.js

单独生成 laroute 路由文件(实测):

sudo -u www-data php artisan laroute:generate

实测输出:

Created: public/js/laroute.js

💡 说明:输出中的 public/js/laroute.js 把后端路由表暴露给前端 JS 使用,由第三方包 axn/laravel-laroute 生成(package:discover 的实测包清单里可见,见 9.4 节)。这两个文件都是构建产物,纳入 freescout:clear-cache 的自动重建链,手动执行仅用于单独刷新。

4.8 freescout:update-folder-counters(重算文件夹计数)

本命令重算全部邮箱文件夹(未分配/打开/挂起/关闭等)的工单计数。Web 界面左栏的计数由后台模式增量维护,若出现「明明有新工单但计数不变」的显示漂移,跑一次本命令即恢复一致。

sudo -u www-data php artisan freescout:update-folder-counters

实测输出:

Updating finished

💡 说明:本环境仅一个演示邮箱、数据量小,执行瞬时完成;生产大数据量下该命令会扫描 conversations 表并按文件夹聚合,建议在低峰期执行。文件夹计数的后台增量模式由 .env 的 APP_FOLDER_COUNTS_BY_BG_JOB 控制,机制说明见 《FreeScout 1.8.248 配置参数详解》。

4.9 数据清理三命令(clean-tmp / clean-notifications-table / clean-send-log)

三条命令各自负责一类旧数据的定期清理,均可安全重复执行(幂等,无旧数据可删时静默完成),适合挂入 cron 周期执行。

① freescout:clean-tmp——清理系统临时目录:删除系统临时目录中 FreeScout 遗留的旧临时文件,官方描述点名用于规避「No space left on device」(临时文件堆积撑爆磁盘的场景)。实测:

sudo -u www-data php artisan freescout:clean-tmp

实测输出:

find: '/tmp/systemd-private-22276d6f23674247bf2c11b0cc0a8f93-systemd-logind.service-7HwYij': Permission denied
find: '/tmp/systemd-private-22276d6f23674247bf2c11b0cc0a8f93-systemd-resolved.service-AISRMd': Permission denied
find: '/tmp/systemd-private-22276d6f23674247bf2c11b0cc0a8f93-systemd-logind.service-7HwYij': Permission denied
find: '/tmp/systemd-private-22276d6f23674247bf2c11b0cc0a8f93-systemd-resolved.service-AISRMd': Permission denied
Done

⚠️ 注意:实测中的 find: Permission denied 是以 www-data 身份扫描系统临时目录时碰到 systemd 私有临时目录(/tmp/systemd-private-*)的正常权限提示,不是故障:这些目录本就只属于 root 对应服务,命令最终输出 Done 表示清理流程完整执行。看到这四行 Permission denied 可直接忽略。

② freescout:clean-notifications-table——清理旧通知记录:删除通知表中已读且超期的记录。实测:

sudo -u www-data php artisan freescout:clean-notifications-table

实测输出:

[2026-10-21 14:42:53] Deleted old read notifications for: -6 months

③ freescout:clean-send-log——清理发送日志:删除邮件发送日志中的旧记录。实测:

sudo -u www-data php artisan freescout:clean-send-log

实测输出:

[2026-10-21 14:42:53] Deleted send logs: -6 months

💡 说明:②③输出中的 -6 months 即保留窗口——只删「已读/超期 6 个月以上」的记录;两条命令都无参数可调保留期,属内置策略。同类的 activitylog:clean(活动日志清理,带参数)见 9.6 节。

4.10 监控三命令(fetch-monitor / send-monitor / logs-monitor)

三条监控命令都由 cron 周期调度(见 6.6 节),也可手动执行做即时诊断:前两条判断抓取/发信链路健康并触发 Web 界面告警,第三条把新日志邮件推送给出设置的收件人。

① freescout:fetch-monitor——抓取健康检查:实测(未配置邮箱时的输出):

sudo -u www-data php artisan freescout:fetch-monitor

实测输出:

[2026-10-21 14:42:42] Fetching has not been configured yet

② freescout:send-monitor——发信队列健康检查:实测(队列正常处理中):

sudo -u www-data php artisan freescout:send-monitor

实测输出:

[2026-10-21 14:42:42] Emails queue processing is working

③ freescout:logs-monitor——日志邮件推送:实测(未在 Web 端选择任何监控日志类别时的输出):

sudo -u www-data php artisan freescout:logs-monitor

实测输出:

[2026-10-21 14:43:09] No logs to monitor selected

💡 说明:三条输出都是「带时间戳的一行状态」。①的 Fetching has not been configured yet 与「抓取中断」状态(配置邮箱后才可能出现)用于区分两种无新信原因;②的 Emails queue processing is working 表示队列 worker 存活;③提示需要先到 Web 端「管理 → 日志监控」勾选要监控的日志等级与收件人,命令才会真正发信。

4.11 freescout:check-conv-viewers(会话查看锁释放)

本命令检查「正在查看会话」的用户是否已实际离开,超时则释放查看锁,避免会话被幽灵锁占用导致他人无法编辑回复。由 cron 每分钟调度(见 6.6 节实测输出中的第二条调度命令),手动执行用于立即释放。

sudo -u www-data php artisan freescout:check-conv-viewers

实测输出:无任何输出(静默完成,退出码 0)。

💡 说明:该命令「无事发生即无输出」,与其他命令的时间戳状态行不同;cron 调用时重定向到 /dev/null(6.6 节),手动执行时同样以退出码判断成败:echo $? 返回 0 即正常。

4.12 模块命令五条(module-build / module-install / module-laroute / module-update / module-check-licenses)

这五条 freescout:module-* 命令服务于 FreeScout 付费/免费模块市场(模块装到 Modules/ 目录):构建、安装(含迁移与符号链接)、生成模块路由 JS、更新、许可检查。除 module-build/module-install/module-laroute/module-update 接受可选参数 module_alias(模块别名,省略则作用于全部模块)外,其余无参数。

本环境未安装任何模块,逐条实测「空模块」状态下的输出:

sudo -u www-data php artisan freescout:module-check-licenses

实测输出:

Active modules found: 0
Checking licenses finished
sudo -u www-data php artisan freescout:module-build

实测输出:

No modules found
sudo -u www-data php artisan freescout:module-laroute

实测输出:

No modules found

💡 说明:module-install 与 module-update 在空模块状态下同样直接结束、无增量输出,故不重复贴回显。装了模块后,这五条与 module:* 系统命令族的分工见第八章末尾的对照说明。

⚠️ 注意:模块安装/更新前先看 freescout:module-check-licenses 的输出——FreeScout 官方模块按许可校验激活,许可异常的模块会在该命令中列出。

4.13 freescout:update 与 freescout:after-app-update(升级链)

两条命令构成 FreeScout 的命令行升级链。freescout:update 从 GitHub 拉取最新版本并完成应用更新(生产环境需 --force 确认);freescout:after-app-update 是更新后的固定收尾序列——源码显示它依次调用 freescout:clear-cache → migrate --force → queue:restart,并触发模块更新事件钩子。

freescout:update 参数(实测 help):

参数含义
--force生产环境下强制执行(无此参数且 APP_ENV=production 时命令要求确认)

⚠️ 注意:本文环境锁定 1.8.248 基准做逐条实测,未实跑 freescout:update(会把应用更到上游最新版,超出本文实测范围)。生产升级的完整流程(升级脚本、备份、回滚)见安装篇第七章「升级、降级与日常管理」;仅当确认要升级时再执行本命令。

freescout:after-app-update 无参数,可安全实跑(三个子命令均幂等):

sudo -u www-data php artisan freescout:after-app-update

实测输出(全量照抄):

The compiled services & packages files have been removed.
Cache cleared successfully.
Compiled views cleared!
Configuration cache cleared!
Configuration cached successfully!
Cleared: JS and CSS builds
Created: /js/builds/vars.js
Nothing to migrate.
Broadcasting queue restart signal.

💡 说明:对照 4.6 节可知前 7 行就是 freescout:clear-cache 的完整输出;随后 Nothing to migrate. 表示数据库结构已最新(迁移机制见第五章);末行 Broadcasting queue restart signal. 由 queue:restart 发出(见 6.3 节)——它让在跑的队列 worker 处理完当前任务后退出,等待 cron 下一轮拉起新代码的 worker。手动升级版本后,依次跑 freescout:update 与本命令即可完成命令行侧的完整升级动作。

五、数据库迁移命令

本章讲解 Laravel 迁移命令族。FreeScout 安装建表、版本升级改表都由这组命令完成,freescout:after-app-update 内部也调用它。本章实测 migrate 与 migrate:status;rollback/reset/refresh/fresh 四条会删除或回滚数据,只给命令形态与官方含义并标注警告,未实跑。

5.1 migrate(执行迁移)

安装篇 5.6 节已用 migrate --force 完成 24 张表的首建(当时输出为逐条 Migrating:/Migrated: 行)。再次执行时,已跑过的迁移会被跳过(实测):

cd /var/www/html
sudo -u www-data php artisan migrate --force

实测输出:

Nothing to migrate.

💡 说明:--force 的作用是跳过生产环境(APP_ENV=production)下的交互确认;不加该参数在生产环境会停下来等输入 yes,cron 与脚本中务必带上。升级 FreeScout 换代码后第一次跑 migrate 时,新迁移会逐条输出 Migrating:/Migrated: 行,与安装篇 5.6 节的回显同型。

5.2 migrate:status(迁移状态)

本命令列出每个迁移文件的执行状态(Y=已执行,N=未执行),是核对「代码版本与数据库结构是否一致」的快查手段。实测输出较长(24 条迁移),保留首尾:

sudo -u www-data php artisan migrate:status

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

+------+----------------------------------------------------------------------------+
| Ran? | Migration                                                                  |
+------+----------------------------------------------------------------------------+
| Y    | 2014_04_02_193005_create_translations_table                                |
| Y    | 2018_06_10_000000_create_users_table                                       |
| Y    | 2018_06_10_100000_create_password_resets_table                             |
| Y    | 2018_06_25_065719_create_mailboxes_table                                   |
| Y    | 2018_06_29_041002_create_mailbox_user_table                                |
......
| Y    | 2026_08_15_010101_update_indexes_in_conversations_table                    |
| Y    | 2026_08_28_010101_add_conversation_id_column_to_notifications_table        |
| Y    | 2026_10_16_010101_update_attachment_tokens_in_bodies                       |
+------+----------------------------------------------------------------------------+

💡 说明:迁移文件名以日期时间开头(如 2026_10_16_010101_update_attachment_tokens_in_bodies),1.8.248 的最后一个迁移是 2026-10-16——上游发布节奏下小版本会新增迁移行;升级后若看到 N(未执行)状态行,跑一次 migrate --force 即对齐。

5.3 回滚类命令(rollback / reset / refresh / fresh)

以下四条命令都会改动数据库表结构与数据,本文按「给出命令形态 + 官方含义 + 强警告」处理,均未实跑(当前环境无待回滚场景,实跑即破坏已建 24 张表):

命令官方含义(help 实测)数据影响
php artisan migrate:rollback --forceRollback the last database migration回滚最后一批迁移(删表/删列)
php artisan migrate:reset --forceRollback all database migrations回滚全部迁移,所有表清空
php artisan migrate:refresh --forceReset and re-run all migrations全部回滚后重建,业务数据丢失
php artisan migrate:fresh --forceDrop all tables and re-run all migrations先删全部表再重建,最彻底

⚠️ 注意:四条命令必须先完成数据备份再考虑,操作后用 migrate:status 核对状态;FreeScout 没有提供「数据回滚」能力,工单、客户、附件一旦随表删除不可恢复。日常运维的正确姿势是:只前滚(migrate --force),不做回滚。

5.4 key:generate(应用密钥)

本命令生成新的 APP_KEY 并写回 .env。仅初始安装、.env 丢失重建时使用:APP_KEY 是会话与加密数据的根基,换钥匙会导致全部现有用户会话失效、加密字段不可解。

sudo -u www-data php artisan key:generate

⚠️ 注意:本文未实跑(当前环境 APP_KEY 已随安装生成且在用,重跑会使在用凭据失效)。安装流程中该命令的执行位置与排障见安装篇 5.5 节。

六、队列与调度命令

本章讲解 FreeScout 异步任务的两条腿:队列(queue)与调度(schedule)。FreeScout 的发信、抓信、后台计数等耗时动作都走队列,cron 每分钟触发的 schedule:run 又负责把队列 worker 拉起来——两条腿的协作机制是运维排障的必修课,先讲机制再逐条讲命令。

6.1 队列运行机制:cron → schedule:run → queue:work

FreeScout 不依赖 systemd 服务或 supervisor 常驻 worker,实测环境中 www-data 的 crontab 只有一行:

sudo crontab -u www-data -l

实测输出:

* * * * * php /var/www/html/artisan schedule:run >> /dev/null 2>&1

每分钟 cron 触发 schedule:run 后,调度器按计划表执行到期命令,其中一项负责把队列 worker 拉起(worker 用完自动退出,下一分钟再拉)。这条链路的三个实证:

  1. schedule:run 的实测输出中可见拉起逻辑(本节 6.6 节照抄了三条调度命令);
  2. 队列中常态存在一个名为 RestartQueueWorker 的任务(queue:work --once 实测处理的就是它,见 6.2 节);
  3. worker 需要重启时用 queue:restart 广播信号,worker 处理完当前任务后退出,等 cron 下一轮重新拉起(freescout:after-app-update 实测末行即它)。

💡 技术拓展:常驻队列 worker 的托管方式不止 FreeScout 这种「cron 拉起」一种。常见方案对比——

方案原理适用场景
cron 拉起(FreeScout 默认)每分钟 schedule:run 顺便启动短命 worker单机、无 root 托管权限,零额外依赖
supervisor 常驻进程管理器常驻 worker,崩溃自动拉起生产推荐,需安装 supervisor
systemd 单元systemctl enable 托管 worker 服务已统一用 systemd 管服务的机器

FreeScout 官方安装文档默认采用 cron 拉起(本文实测环境即此形态);流量大的站点可自行改用 supervisor 常驻 worker 以降低每分钟冷启动开销,worker 命令不变(见 6.2 节)。

6.2 queue:work(队列 worker)

本命令启动队列 worker 处理任务。实测 help 输出的完整参数表:

参数默认值含义
<connection>(可选参数)框架默认连接队列连接名(database 等)
--queue—只处理指定队列名
--daemon—守护模式(已标记 Deprecated)
--once—只处理一个任务即退出
--delay"0"失败任务的重试延迟秒数
--force—维护模式下仍继续处理
--memory"128"内存上限(MB),超限自杀重启
--sleep"3"无任务时休眠秒数
--timeout"60"单任务最长运行秒数
--tries"0"任务重试次数上限

单步实测(处理一个任务即退出,适合验证队列通路):

sudo -u www-data php artisan queue:work --once

实测输出:

[2026-10-21 14:43:20] Processing: App\Jobs\RestartQueueWorker

💡 说明:实测处理的正是 FreeScout 常驻队列里的 RestartQueueWorker 任务——队列空转时它的职责是确保 worker 按需重启,这条回显同时证明了「队列连接正常 + worker 可执行任务」两件事。

⚠️ 注意(排障实录):Laravel 新版教程常见的 --stop-when-empty 参数在 FreeScout 的框架版本(5.5.40 fork)中不存在,实测报错:

sudo -u www-data php artisan queue:work --once --stop-when-empty

实测输出:



  The "--stop-when-empty" option does not exist.


遇到该报错去掉 --stop-when-empty、只用 --once 即可(等价语义:处理完现有任务后退出)。

6.3 queue:restart(广播重启信号)

本命令向所有在跑的 worker 广播「处理完当前任务后退出」的信号,worker 随后被 cron 拉起加载新代码。升级代码、改完队列相关配置后执行。实测:

sudo -u www-data php artisan queue:restart

实测输出:

Broadcasting queue restart signal.

6.4 失败任务四命令(failed / retry / forget / flush)

任务重试超限(--tries)后会落入 failed_jobs 表,四条命令负责查看与善后。逐条实测(当前环境无失败任务,输出即空态形态):

sudo -u www-data php artisan queue:failed

实测输出:

No failed jobs!
sudo -u www-data php artisan queue:retry <失败任务ID>

💡 说明:queue:retry 按失败任务的 ID 重新入队,queue:forget <ID> 删除单条失败记录,queue:flush 清空全部失败记录。三者均需以 queue:failed 列出的真实 ID 为参数,空表时无操作对象,故本文仅实测了 queue:failed 的空态输出,其余未实跑。

6.5 queue:listen 与建表命令(listen / table / failed-table)

queue:listen 是 worker 的另一种运行方式:每次任务起一个子进程执行(省内存但开销大),适合开发调试;queue:table/queue:failed-table 生成队列表的迁移文件(安装时已随应用迁移建好 jobs/failed_jobs 表,正常运维无需再跑)。命令形态:

sudo -u www-data php artisan queue:listen
sudo -u www-data php artisan queue:table
sudo -u www-data php artisan queue:failed-table

⚠️ 注意:queue:listen 是前台常驻命令,排障时临时观察队列行为用,观察完 Ctrl+C 退出;queue:table 类命令会向 database/migrations/ 写入新迁移文件,执行后需跑 migrate 才生效——1.8.248 安装时队列与失败表已建好,无需重复执行。

6.6 schedule:run(调度入口)

本命令按调度计划表执行「当前这一分钟到期」的全部命令,是 crontab 唯一调用的 artisan 命令。手动执行一次可看到本轮实际调度的命令清单(实测):

sudo -u www-data php artisan schedule:run

实测输出(本轮到期三条,全量照抄):

Running scheduled command: '/usr/bin/php8.3' 'artisan' freescout:fetch-monitor > '/dev/null' 2>&1
Running scheduled command: '/usr/bin/php8.3' 'artisan' freescout:check-conv-viewers > '/dev/null' 2>&1
Running scheduled command: '/usr/bin/php8.3' 'artisan' freescout:fetch-emails --identifier=73907a81d9699ef4112b47bfbf70cf78 --unseen=1 > '/var/www/html/storage/logs/fetch-emails.log' 2>&1

💡 说明:三条调度命令对应 4.10 ①、4.11、4.4 三节——抓取监控与查看锁检查每分钟静默执行(输出进 /dev/null),邮件抓取同样每分钟执行但日志落到 storage/logs/fetch-emails.log(排障时先看这个文件)。--identifier 的 32 位随机串防并发抓取。手动执行时若本轮恰好无到期任务,则无输出。

⚠️ 注意:安装篇 5.10 节已沉淀过关键排障结论——cron 行不要加 --no-interaction:schedule:run 每次执行会顺便拉起后台 queue:work,加该参数会导致守护进程起不来、发信等异步任务全部卡住。

七、缓存与配置命令

本章讲解缓存与配置维护命令。FreeScout 已提供一站式 freescout:clear-cache(4.6 节),Laravel 原生命令在此的作用是细粒度处理:只清某一类缓存、或单独重建某层。每条实测空态回显。

7.1 cache:clear / cache:forget / cache:table

应用数据缓存(文件/Redis 等驱动)的清理命令。实测:

sudo -u www-data php artisan cache:clear

实测输出:

Cache cleared successfully.
sudo -u www-data php artisan cache:forget <键名>

💡 说明:cache:forget 按键名单删,键名以 cache:clear 前置的清单为准,本文未逐键实测;cache:table 生成缓存表迁移(仅使用 database 缓存驱动时需要,本文环境用默认文件驱动,未实跑)。

7.2 config:cache / config:clear

配置缓存的重建与清理。实测两条连跑:

sudo -u www-data php artisan config:cache
sudo -u www-data php artisan config:clear

实测输出:

Configuration cache cleared!
Configuration cached successfully!
Configuration cache cleared!

💡 说明:config:cache 先清后建(前两行),config:clear 只清(第三行)。关键差异:FreeScout 读取 .env 的参数在配置缓存重建后即固化,此后手改 .env 不生效,必须再跑 config:cache(或 4.6 节的一站式命令)——「改了配置没生效」的排查路径详见 《FreeScout 1.8.248 配置参数详解》第三章。

7.3 route:list / route:cache / route:clear

route:list 列出全部已注册 HTTP 路由,验证某 URL 归属哪个控制器时用。实测输出较长(保留首尾):

sudo -u www-data php artisan route:list

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

+--------+----------------------------------------+------------------------------------------------------------+------------------------------------------+------------------------------------------------------------------------------------+-------------------------+
| Domain | Method                                 | URI                                                        | Name                                     | Action                                                                             | Middleware              |
+--------+----------------------------------------+------------------------------------------------------------+------------------------------------------+------------------------------------------------------------------------------------+-------------------------+
|        | GET|HEAD                               | /                                                          | dashboard                                | App\Http\Controllers\SecureController@dashboard                                    | web,auth                |
|        | GET|HEAD                               | app-logs/app                                               | logs.app                                 | \Rap2hpoutre\LaravelLogViewer\LogViewerController@index                            | web,auth,roles          |
|        | GET|HEAD                               | app-logs/{name?}                                           | logs                                     | App\Http\Controllers\SecureController@logs                                         | web,auth,roles          |
......
|        | GET|HEAD                               | users/wizard                                               | users.create                             | App\Http\Controllers\UsersController@create                                        | web,auth                |
|        | POST                                   | users/wizard                                               |                                          | App\Http\Controllers\UsersController@createSave                                    | web,auth                |
+--------+----------------------------------------+------------------------------------------------------------+------------------------------------------+------------------------------------------------------------------------------------+-------------------------+

route:cache/route:clear 生成/清理路由缓存文件(与 7.2 同理:缓存固化后新增路由不生效):

sudo -u www-data php artisan route:cache
sudo -u www-data php artisan route:clear

💡 说明:本文未实跑 route:cache(该环境路由缓存未启用,固化操作留给有明确性能诉求的读者在测试环境先行验证);FreeScout 前端 JS 用的路由表走 laroute 通道(4.7 节),与此处的 HTTP 路由缓存是两回事。

7.4 view:clear / clear-compiled / optimize

编译产物清理三件套。实测:

sudo -u www-data php artisan view:clear

实测输出:

Compiled views cleared!

clear-compiled 清理框架编译类文件(freescout:clear-cache 的第一步即它,实测输出 The compiled services & packages files have been removed.);optimize 是框架遗留命令(list 中已标注 deprecated),实测执行无输出,FreeScout 环境用一站式命令替代,无需单独使用。

7.5 down / up(维护模式)

维护模式开关:down 让应用对所有 Web 请求返回 503(升级、大规模维护时使用),up 恢复。实测完整闭环(down 后立即验证再 up):

sudo -u www-data php artisan down

实测输出:

Application is now in maintenance mode.

此时浏览器访问应用(实测 curl 状态码):

HTTP 503

恢复:

sudo -u www-data php artisan up

实测输出:

Application is now live.

恢复后再次访问(实测):

HTTP 302

💡 说明:302 是恢复后首页对未登录请求的跳转(跳登录页),即应用已正常服务。附带一个实测发现:若请求的 Host 头与应用地址不符(如直接用 127.0.0.1 访问),FreeScout 返回 403 而非 302——这是应用层的主机名校验(403 Untrusted Host,安装篇 5.8 节的 Nginx APP_URL 配置与之呼应),排障时注意区分。

⚠️ 注意:维护模式下队列 worker 默认也停止接受任务;如需维护期间继续处理队列,给 worker 加 --force(6.2 节参数表)。freescout:after-app-update 升级链不受维护模式影响。

八、模块系统命令

本章讲解 module:* 命令族(30 条,来自 nwidart/laravel-modules 包)。FreeScout 的功能模块(官方市场购买或第三方)以 Laravel Module 形态安装在 Modules/ 目录,这组命令管理模块的全生命周期。本文环境未安装模块,先看模块清单的空态(实测):

sudo -u www-data php artisan module:list

实测输出:

+------+--------+-------+------+
| Name | Status | Order | Path |
+------+--------+-------+------+

8.1 模块生命周期核心命令

命令官方含义说明
php artisan module:install <vendor/name>Install the specified module by given package name (vendor/name)用 composer 包名安装模块
php artisan module:enable <别名>Enable the specified module.启用模块
php artisan module:disable <别名>Disable the specified module.停用模块(不卸载)
php artisan module:update <别名>Update dependencies for the specified module or for all modules.更新模块依赖
php artisan module:migrate <别名>Migrate the migrations from the specified module or from all modules.执行模块自带迁移
php artisan module:publish <别名>Publish a module's assets to the application发布模块静态资产

8.2 模块开发命令(make/publish 族)

module:make* 12 条为模块二次开发脚手架(生成 controller/model/migration 等),module:publish-* 4 条发布模块配置/迁移/翻译,module:use/module:unuse 切换命令行当前模块上下文,module:setup 初始化模块目录结构。完整清单见第二章 php artisan list 实测输出的 module 分组。

8.3 freescout:module-* 与 module:* 的关系

两族命令分工:freescout:module-*(4.12 节)是 FreeScout 定制封装——freescout:module-install 在安装同时跑迁移并创建符号链接、freescout:module-laroute 生成模块路由 JS、freescout:module-check-licenses 校验官方许可,装 FreeScout 模块优先用这一族;module:* 是通用模块框架命令,处理启用/停用/发布等通用操作。日常运维组合拳:装/升级模块用 freescout:module-*,启停与资产发布用 module:*。

⚠️ 注意:module:migrate-refresh / module:migrate-reset / module:migrate-rollback 三条会回滚模块数据表,与 5.3 节回滚类命令同级危险,实跑前务必备份。

九、辅助与开发命令

本章收拢其余常用命令:交互式调试、环境确认、密钥与符号链接、翻译与活动日志、版本检查,以及二次开发向的脚手架族。运维重点前三节,开发向仅列清单。

9.1 tinker(交互式调试台)

tinker 打开一个 REPL 交互环境,可直接执行任意 PHP 代码与 Eloquent 查询,是「不写脚本就能查库、调配置」的利器。排障实录(真实踩坑):直接以 sudo -u www-data 运行会报错——

sudo -u www-data php artisan tinker

实测报错:

In ConfigPaths.php line 228:

  Writing to /var/www/.config/psysh is not allowed.

原因:tinker(Psy Shell)要往运行用户的 HOME/.config/psysh 写历史与配置,sudo 切换后 HOME 指向了 /var/www(不可写)。解决:显式把 HOME 指到应用可写目录。实测修正后执行查询(管道传入两行代码):

echo 'echo "APP_NAME: ".config("app.name"); echo PHP_EOL; echo "USERS: ".\App\User::count();' | sudo -u www-data HOME=/var/www/html php artisan tinker

实测输出(节选):

Psy Shell v0.9.12 (PHP 8.3.35 — cli) by Justin Hileman
APP_NAME: FreeScout
USERS: 2⏎

/var/www/html/overrides/psy/psysh/src/Shell.php (390): Exit:  Ctrl+D

💡 说明:首行是 Psy Shell 版本横幅;两行查询结果分别读到了配置值 FreeScout 与用户表计数;末行是 tinker 在非交互(管道)模式下的退出提示。交互式使用时直接 sudo -u www-data HOME=/var/www/html php artisan tinker 进入,Ctrl+D 退出。4.2 节创建/删除用户的验证即用此通道完成。

9.2 env / inspire / help / list / --version

环境确认与杂项。实测:

sudo -u www-data php artisan env

实测输出:

Current application environment: production

php artisan inspire 输出一条随机名言(实测:Simplicity is an acquired taste. - Katharine Gerould),常用于验证 CLI 通路;help <命令> 与 list 用法见第二章;php artisan --version 见第三章。

9.3 storage:link(符号链接)

本命令在 public/storage 创建指向 storage/app/public 的符号链接,使上传的公开文件可经 Web 直接访问。安装时已执行过,重复执行的真实回显(排障素材):

sudo -u www-data php artisan storage:link

实测输出:

The "public/storage" directory already exists.

💡 说明:看到 already exists 即链接已就位,非故障;若链接被误删,重新执行本命令即可重建。

9.4 auth:clear-resets / package:discover

auth:clear-resets 清理过期的密码重置令牌(实测):

sudo -u www-data php artisan auth:clear-resets

实测输出:

Expired reset tokens cleared!

package:discover 重建 composer 包清单缓存(升级后包异常时用),实测输出(全量照抄):

Discovered Package: axn/laravel-laroute
Discovered Package: barryvdh/laravel-translation-manager
Discovered Package: chumper/zipper
Discovered Package: fideloper/proxy
Discovered Package: javoscript/laravel-macroable-models
Discovered Package: laravel/tinker
Discovered Package: mews/purifier
Discovered Package: nesbot/carbon
Discovered Package: nwidart/laravel-modules
Discovered Package: rachidlaasri/laravel-installer
Discovered Package: rap2hpoutre/laravel-log-viewer
Discovered Package: spatie/laravel-activitylog
Discovered Package: tormjens/eventy
Package manifest generated successfully.

💡 说明:这份包清单同时是 FreeScout 1.8.248 依赖栈的实证——翻译管理(barryvdh)、HTML 净化(mews/purifier)、活动日志(spatie)、事件钩子(tormjens/eventy)、安装器(rachidlaasri)等核心能力都来自这些包。

9.5 db:seed(测试数据填充——慎用)

本命令执行 database/seeds/DatabaseSeeder.php 填充数据。实测环境未执行——经源码核对,该 seeder 会真实创建 3 个用户、3 个邮箱及各自带 7 条会话线程的演示数据,跑完即污染生产库。仅作说明:

sudo -u www-data php artisan db:seed --force

⚠️ 注意:db:seed 适合全新空库演练或开发环境造数;生产环境误跑后的清理需逐表删除 factory 生成的用户/邮箱/客户/会话,成本高。确需演示数据请在隔离环境执行。

9.6 translations:* 与 activitylog:clean

FreeScout 内置翻译管理(数据库存翻译,可导出回 PHP 文件),五条 translations:* 命令中 translations:clean 清理空翻译记录,实测安全:

sudo -u www-data php artisan translations:clean

实测输出:

Done cleaning translations

translations:import/export/find/reset 用于翻译的导入导出与重置,其中 translations:reset 会清空数据库翻译(回退到 PHP 源文件),实跑前备份。

活动日志清理命令(参数化保留期):

sudo -u www-data php artisan activitylog:clean --days=180

实测输出(默认清理行为):

Cleaning activity log...
Deleted 0 record(s) from the activity log.
All done!

💡 说明:实测输出 Deleted 0 record(s) 因本环境无超期活动日志;--days 参数控制保留天数(不传时用 spatie/laravel-activitylog 包配置的默认值)。

9.7 updater:check-for-update(检查新版本)

检查 GitHub 上游是否有新版本(联网查询),不执行更新。实测:

sudo -u www-data php artisan updater:check-for-update

实测输出:

There's no new version available.

💡 说明:该输出即 2026-10-21 实测时上游最新版仍为 1.8.248 的命令行佐证(与第一章版本时效说明互证);有新版本时会提示可用版本,升级动作仍走 freescout:update(4.13 节)。

9.8 开发向命令清单(make:* / vendor:publish / event:generate / preset / app:name)

以下命令面向二次开发(会向源码目录写文件或改动命名空间),运维场景不使用,实测仅核对命令注册,均未实跑执行体:

命令族数量用途
make:command/controller/model/migration/...20生成应用层各类代码骨架(含 make:auth 登录脚手架)
module:make*12同上,作用于模块目录(见 8.2 节)
vendor:publish1发布 vendor 包的可发布资产(配置/视图等)
event:generate1依据监听器补生成缺失的事件类
preset1切换前端脚手架(框架遗留)
app:name1改写应用命名空间(慎用,全库改名)

十、注意事项

本章汇总全文实测沉淀的操作纪律,逐条执行可避开实测中遇到与规避的坑。

  1. 执行身份必须是 www-data:统一 sudo -u www-data php artisan ...。root 直跑会把缓存产物属主改坏,Web 端随即写缓存报错。
  2. 生产环境迁移/种子命令带 --force:migrate、db:seed 在 APP_ENV=production 下默认停下等确认,脚本与 cron 中必须显式 --force(实测 5.1 节)。
  3. 改 .env 后必须重建配置缓存:freescout:clear-cache(一站式)或 config:cache,否则改动不生效(7.2 节机制)。
  4. 回滚类命令先备份:migrate:rollback/reset/refresh/fresh 与 module:migrate-* 三条回滚命令都删表删数据,FreeScout 无数据回滚能力(5.3/8.3 节)。
  5. cron 行不加 --no-interaction:会阻断 schedule:run 拉起队列 worker,发信全卡(6.6 节,安装篇 5.10 节实测结论)。
  6. 框架版本陷阱:--stop-when-empty 等 Laravel 新版参数在本 fork 中不存在(6.2 节报错实录);tinker 需 HOME=/var/www/html 修正配置目录(9.1 节)。
  7. 升级三步固定:换代码 → freescout:after-app-update(含清缓存/迁移/重启队列)→ migrate:status 核对全 Y;上游是否有新版先用 updater:check-for-update 探查(9.7 节)。
  8. 维护模式时间窗:down 期间 Web 全站 503,队列也停(除非 worker --force);操作完立即 up(7.5 节)。
  9. clean-tmp 的 Permission denied 可忽略:www-data 扫不到 systemd 私有临时目录属正常,以最终 Done 为准(4.9 节)。
  10. parse-eml 只认固定路径:storage/logs/email.eml,测完删除测试文件(4.5 节)。

十一、常见问题

Q1:php artisan 报 Could not open input file: artisan? 当前目录不对。artisan 必须在应用根目录执行:cd /var/www/html 后重试。多站点机器上先确认目标站点根路径(本文环境为 /var/www/html)。

Q2:命令能跑但 Web 端开始报存储/缓存权限错误? 大概率用了 root 跑过 artisan,缓存产物属主已变 root。修复:sudo chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache,随后再跑一次 freescout:clear-cache 重建。预防:养成 sudo -u www-data 习惯(注意事项 1)。

Q3:改了 .env 为什么不生效? FreeScout 会固化配置缓存(config:cache 先清后建,见 7.2 节)。执行 sudo -u www-data php artisan freescout:clear-cache 一站式重建后刷新验证;完整的配置层次与验证方法见 《FreeScout 1.8.248 配置参数详解》。

Q4:邮件不进来了,先查哪条命令? 顺序:freescout:fetch-monitor——输出 Fetching has not been configured yet 是从未配置,否则继续;看 storage/logs/fetch-emails.log(cron 抓取日志落点,6.6 节);手动 freescout:fetch-emails --debug=1 复现抓取过程;freescout:send-monitor 确认队列 worker 存活(4.10/4.4/6.1 节)。

Q5:queue:work 报 The "--stop-when-empty" option does not exist.? 该参数不存在于此框架版本(6.2 节排障实录),去掉后用 --once 达到「处理完即退」语义。

Q6:tinker 报 Writing to /var/www/.config/psysh is not allowed.? HOME 指向不可写目录(9.1 节排障实录),改用 sudo -u www-data HOME=/var/www/html php artisan tinker。

Q7:文件夹工单计数与列表不一致? 跑 freescout:update-folder-counters 重算(4.8 节);若频繁漂移,检查 .env 的后台计数模式配置(配置篇)。

Q8:升级后如何确认一切就绪? 固定三查:freescout:check-requirements(环境全 OK,4.1 节)→ migrate:status(全 Y,5.2 节)→ freescout:module-check-licenses(模块许可正常,4.12 节);再登录 Web 验证收发信。

Q9:freescout:clean-tmp 输出一堆 Permission denied 正常吗? 正常。www-data 无权扫描 systemd 私有临时目录,见 4.9 节实录;以结尾 Done 为准。

Q10:命令输出里的时间戳与服务器时间对不上? 应用时区由 .env 的 APP_TIMEZONE 决定(本文实测环境基线为 UTC,配置篇第一章有基线取证),与系统时区(Asia/Shanghai 等)不同属正常,对比日志时注意换算。

十二、参考链接