这是一个面向 Linux 场景的自动化处理脚本集,用来持续监控目录中的压缩包与图片文件,并自动完成:
- 压缩包稳定性检测
- 多引擎解压
- 密码尝试
- 文件筛选与复制
- 失败归档
- 图片自动分组
- systemd 服务托管
- 定时清理遗留数据
- 缺失目录自动补建
- 缺失依赖自动安装
当前仓库的核心文件只有 3 个:
scan.js:主程序,负责真正的监控、解压、筛选、复制、校验与失败处理scan.sh:控制脚本,负责路径配置、依赖安装/检查、systemd 服务管理、定时清理管理zip.sh:独立的解压环境检测脚本
这不是 npm 项目,仓库中没有
package.json。运行依赖主要来自 Linux 系统命令与 Node.js 运行时。
scan.js 会持续扫描 WATCH_DIR 中的以下压缩包:
.zip.7z.rar
处理流程大致如下:
- 每 2 秒扫描一次监控目录
- 找到压缩包后,先等待文件大小稳定,避免上传中半成品被提前处理
- 创建
.lock文件,避免重复处理同一个任务 - 将压缩包复制到本地临时目录
LOCAL_DIR - 依次使用可用解压工具尝试解压:
7zzunzipunrarbsdtar
- 解压时会遍历密码文件,同时默认优先尝试空密码
- 解压成功后,自动判断结果中是否还存在“内层压缩包”
- 根据判断结果清理无关文件:
- 如果存在内层压缩包:只保留内层压缩包
- 否则:只保留图片和视频文件
- 将结果复制回监控目录中,以压缩包名生成目标目录
- 对复制结果做“总大小 + 文件数量”校验
- 校验成功后删除源压缩包、本地副本和临时目录
- 校验失败或解压失败时,将原始压缩包移动到失败目录
FAILED_DIR
除了压缩包处理,scan.js 还会监听 WATCH_DIR 中新增的图片文件。
它会把 20 秒内进入目录的图片归为一组,并自动完成:
- 新建图片组目录
- 按首图时间确定分组命名
- 组稳定后将目录重命名为首图名
- 将首图重命名为
1.<ext> - 尝试清理图片分组过程中遗留的空目录
当前版本已经支持目录自愈。
以下路径如果不存在,会在合适时机自动创建:
WATCH_DIRLOCAL_DIRFAILED_DIRERROR_LOG的父目录SUCCESS_LOG的父目录LOG_FILE的父目录
也就是说,现在即使这些目录一开始没手工创建,脚本也会尽量自己补齐。
scan.sh 现在默认支持“检测不到就尝试自动安装依赖”。
覆盖范围包括:
node/nodejs7zz / 7zunrarbsdtarunzipsystemd(按环境尽力安装)
当前支持识别这些常见包管理器:
apt-getdnfyumpacmanapkzypper
说明:
- 默认开启自动安装
deps和health都会默认触发这套逻辑- 你也可以显式执行一键安装命令:
install-deps - 如果你只想检查、不想安装,可使用:
--no-auto-install - Alpine /
apk环境通常不是 systemd 体系,因此会跳过 systemd 的强装逻辑
当前项目已支持通过 scan.sh 创建并管理 systemd timer,用来每天固定时间清理遗留数据。
清理内容包括两类:
- A:
LOCAL_DIR中的残留临时目录、旧压缩包副本、旧.lock - B:
FAILED_DIR中超过保留天数的旧文件
.
├── scan.js # Node.js 主程序
├── scan.sh # 控制脚本 / 部署脚本 / 运维入口
├── zip.sh # 解压环境测试脚本
└── README.md
注意:当前本地仓库中没有
passwords.example.txt,但有一个实际存在的passwords.txt。如果你不使用仓库根目录下这份密码文件,也可以自行创建新的密码文件,并通过PASSWORD_FILE指定它。
- Linux 环境
- Bash
- Node.js
推荐安装:
7zzunzipunrarbsdtar
这一点非常重要:
scan.js实际优先调用的是7zz- 如果系统里只有
7z,scan.sh会把它视为“不完整可用”并继续尝试补装7zz / 7zip
因此最稳妥的部署方式仍然是:确保系统里最终可直接执行 7zz。
如果你只打算手动运行 node scan.js,那 systemd 不是绝对必须。
如果你希望长期常驻运行、使用 scan.sh create/start/enable、以及启用定时清理,那么 systemd 才真正有价值。
scan.js 使用环境变量读取配置,如果未设置则使用默认值:
| 变量名 | 默认值 | 说明 |
|---|---|---|
WATCH_DIR |
/mnt/notify/shared/bot/cos |
监控目录 |
LOCAL_DIR |
/root/scan/chane |
本地临时目录 |
PASSWORD_FILE |
/root/scan/passwords.txt |
密码文件路径 |
ERROR_LOG |
/root/scan/error.log |
错误日志 |
SUCCESS_LOG |
/root/scan/success.log |
成功日志 |
FAILED_DIR |
/root/scan/failed |
失败文件目录 |
| 变量名 | 默认值 | 说明 |
|---|---|---|
SERVICE_NAME |
cos-watcher |
systemd 服务名 |
SCAN_DIR |
/root/scan |
项目目录 |
JS_FILE |
${SCAN_DIR}/scan.js |
主程序入口文件 |
LOG_FILE |
${SCAN_DIR}/scan.log |
systemd 追加日志 |
SERVICE_FILE |
/etc/systemd/system/${SERVICE_NAME}.service |
主服务文件 |
SERVICE_USER |
root |
服务运行用户 |
RESTART_POLICY |
always |
systemd 重启策略 |
CONFIG_FILE |
/etc/cos-watcher.env |
持久化配置文件 |
| 变量名 | 默认值 | 说明 |
|---|---|---|
CLEANUP_ENABLED |
false |
是否启用定时清理 |
CLEANUP_DAILY_TIME |
03:30 |
每日执行时间,格式 HH:MM |
LOCAL_RESIDUAL_MAX_AGE_DAYS |
1 |
本地残留清理天数 |
FAILED_RETENTION_DAYS |
7 |
失败目录保留天数 |
CLEANUP_LOCAL_RESIDUAL |
true |
是否清理本地残留 |
CLEANUP_FAILED_OLD |
true |
是否清理失败目录旧文件 |
主程序会从 PASSWORD_FILE 指定的文件中按行读取密码。
格式示例:
123456
password
abc123
当前逻辑特点:
- 一行一个密码
- 自动去重
- 自动把空密码放在最前面优先尝试
- 不会特殊识别注释行,因此不要把说明文字写进去
如果你还没有这个文件,可以自己创建:
mkdir -p /root/scan
cat > /root/scan/passwords.txt <<'EOF'
123456
password
EOF先运行依赖检查(默认会尝试自动安装):
bash scan.sh deps或者显式执行一键安装/修复依赖:
bash scan.sh install-deps如果你只想检查、不想自动安装:
bash scan.sh deps --no-auto-install然后直接运行主程序:
node scan.jsexport WATCH_DIR=/data/incoming
export LOCAL_DIR=/data/chane
export PASSWORD_FILE=/root/scan/passwords.txt
export ERROR_LOG=/root/scan/error.log
export SUCCESS_LOG=/root/scan/success.log
export FAILED_DIR=/root/scan/failed
node scan.jsbash zip.sh这个脚本会:
- 创建测试文件
- 使用
zip创建 ZIP 测试包 - 使用
rar创建 RAR 测试包 - 检查
7z - 检查
unzip - 检查
unrar - 给出彩色结果输出
注意:
zip.sh里检查的是7z,而scan.js真正优先使用的是7zz。另外,zip.sh在测试 ZIP / RAR 时还会用到zip和rar来生成测试包,所以如果这两个命令不存在,测试结果也会受到影响。
scan.sh 是整个项目的主控制入口,既支持命令行模式,也支持交互菜单。
bash scan.sh如果是在交互终端里执行,它会进入菜单;如果是在非交互环境里执行,则会默认改为运行 health。
进入交互菜单后,当前主要菜单项含义如下:
1:创建/更新服务2:设置路径位置并保存3:启动服务4:设置开机自动启动5:查看当前状态6:查看实时日志7:重启服务8:停止服务9:健康检查10:一键安装/修复依赖11:查看当前路径配置12:关闭开机自动启动13:卸载服务14:立即执行一次清理15:设置定时清理
当前已经改成中文向导式:
- 每一项都会显示当前值
- 直接回车就沿用当前值
- 布尔项支持输入
是 / 否 - 最后会再次确认是否保存
当前会先显示缺失依赖摘要,再询问是否继续安装:
- 先列出当前缺失项
- 再提示是否立即安装/修复
- 不确认则返回主菜单
当前会:
- 先显示当前定时器状态
- 再显示当前清理时间
- 然后询问是否修改时间
- 不修改则直接返回
bash scan.sh help当前支持的主要命令:
menucreateset-pathstartenablestatusdepsinstall-depscleanup-runcleanup-statuslogsrestartstophealthshow-pathdisableuninstallversionhelp
bash scan.sh set-path \
--watch-dir /data/incoming \
--local-dir /data/chane \
--password-file /root/scan/passwords.txt \
--error-log /root/scan/error.log \
--success-log /root/scan/success.log \
--failed-dir /root/scan/failed \
--cleanup-enabled true \
--cleanup-time 03:30 \
--local-residual-days 1 \
--failed-retention-days 7 \
--cleanup-local-residual true \
--cleanup-failed-old truebash scan.sh show-pathbash scan.sh createbash scan.sh startbash scan.sh enablebash scan.sh statusbash scan.sh logsbash scan.sh cleanup-runbash scan.sh cleanup-statusbash scan.sh healthbash scan.sh stop
bash scan.sh restart
bash scan.sh uninstall如果你准备把它作为 Linux 上的长期运行任务,建议按这个顺序:
bash scan.sh install-deps
bash scan.sh set-path --watch-dir /data/incoming --local-dir /data/chane
bash scan.sh health
bash scan.sh create
bash scan.sh start
bash scan.sh enable如果启用了:
CLEANUP_ENABLED=true
那么执行 start / enable 时,也会同时联动启动和启用 cleanup timer。
当前使用 systemd timer,不是 cron。
会生成:
${SERVICE_NAME}-cleanup.service${SERVICE_NAME}-cleanup.timer
调度规则为:
OnCalendar=*-*-* HH:MM:00
示例:每天凌晨 2:15 清理本地残留和失败目录旧文件:
bash scan.sh set-path \
--cleanup-enabled true \
--cleanup-time 02:15 \
--local-residual-days 1 \
--failed-retention-days 14 \
--cleanup-local-residual true \
--cleanup-failed-old true
bash scan.sh create
bash scan.sh enable
bash scan.sh start关闭定时清理:
bash scan.sh set-path --cleanup-enabled false
bash scan.sh disable
bash scan.sh enable注意:上面这组命令不只是影响清理定时器,也会同时影响主服务的开机自启状态,因为当前脚本会把两者联动处理。
当前项目里有三类日志:
ERROR_LOG:主程序错误日志SUCCESS_LOG:主程序成功日志LOG_FILE:systemd 服务标准输出/错误追加日志
额外行为:
scan.js会定期清理ERROR_LOG和SUCCESS_LOG中 30 分钟之前的旧内容
项目主要面向:
- Linux
- Bash
- systemd
在 Windows、本地无 systemd 容器、WSL、精简发行版里,部分服务管理能力可能不可用。
当前处理逻辑是:
- 一次只取监控目录中的第一个压缩包处理
- 并不是多任务并行解压队列
处理压缩包时会在原文件旁边生成 .lock 文件,避免重复处理。
虽然 scan.sh 已经支持按包管理器自动安装,但不同发行版仓库策略不同,例如:
unrar可能受非自由仓库策略影响7zip/7zz的包名在不同系统间可能不同systemd在非 systemd 体系里未必适合安装
所以“自动安装”是尽力而为,不是 100% 保证成功。
zip.sh检查的是7zscan.js真正优先使用的是7zz
部署时要特别注意这一点。
先尝试:
bash scan.sh install-deps如果你只想看结果,不想改系统:
bash scan.sh deps --no-auto-install建议依次检查:
bash scan.sh health
bash scan.sh status
bash scan.sh logs重点确认:
SCAN_DIR是否正确JS_FILE是否存在node/nodejs是否可执行- 服务用户是否有目录权限
- 当前环境是否真的支持 systemd
常见原因包括:
- 密码不正确
- 解压工具没装全
- 压缩包损坏
- 解压后校验失败
排查时重点看:
ERROR_LOGSUCCESS_LOGLOG_FILE
当前版本一般会自动补建以下目录:
WATCH_DIRLOCAL_DIRFAILED_DIR- 日志目录
如果依然创建失败,通常是权限问题。
当前仓库里没有 LICENSE 文件。
如果你准备对外分发,建议补充许可证说明。