做音乐本地归档这件事,我折腾过不少方案。早期用网页端一个个点,后来写脚本抓页面,再后来干脆退回终端,用一个命令行工具把整个流程固化下来。标题里提到的这类工具,本质上是把“解析链接—获取音频流—写入标签—落盘校验”这条链路做成了终端里的几条命令,核心关键词就是终端、无损音乐、命令行、批量归档。它解决的是三个很具体的痛点:网页端一次只能下一首、元数据和封面经常丢、大批量任务中途断了要重来。适合谁来参考?手上有正规订阅或已购买内容、想把曲库落到自己硬盘上长期保存的人;喜欢用脚本串流程的人;以及那些对音质参数、标签规范有洁癖的人。下面这份内容,我会把选型逻辑、参数换算、实操命令、踩坑记录全部摊开讲,工具统一用虚构项目名hires-dl代指,平台统一称为“该高解析音乐服务”,你把它理解成任意一个提供无损音频且开放了个人账号接口的服务即可。
1. 项目整体设计与思路拆解
1.1 为什么在音乐归档场景里,命令行反而打得过图形界面
先说结论:单次下载三五首,图形界面确实舒服;一旦你的目标变成“把我账号下收藏的两千多首完整落到硬盘”,图形界面就彻底输了。
原因不在于界面好不好看,而在于三件事。第一是可编排。归档从来不是一次性动作,而是长期维护——每月新增的收藏、每季度补一次漏、每年做一次全库校验。命令行天然能被脚本、定时任务、日志系统包住,你能把它变成一条流水线;图形界面只能靠手点,点一百次和点一万次的差别是灾难性的。
第二是可复现。同一条命令配同一份配置,今天跑和半年后跑,产出的目录结构、文件命名、标签写入规则完全一致。曲库这东西最怕标准漂移,前年按“歌手/专辑/曲序”存,去年按“歌手 - 专辑/曲名”存,三年后你的库就是一锅粥。命令行把标准写进配置里,成了硬约束。
第三是可观测。终端里每一条进度、每一次重试、每一个失败文件名都能进日志文件。批量任务最怕的其实是“静默失败”——界面显示完成了,实际少了二十首,你半年后才发现。命令行能让失败显式暴露出来,甚至能让脚本在失败率超阈值时直接退出并告警。
我在实际使用中形成的一个判断标准是这样的:如果一个资源你预期会反复获取、且总量超过一两百个文件,就值得为它写一套命令行流程;低于这个量级,别浪费时间。工具是手段,不是信仰。
1.2 技术架构:把“下载”这件小事拆成四层
很多人以为这类工具就是“发个请求拿文件”,真拆开看,它至少有四层,每层都有独立的失败模式:
| 层 | 职责 | 典型失败 |
|---|---|---|
| 接口层 | 登录态维护、签名计算、请求重试 | 登录态过期、频率限制、签名不匹配 |
| 解析层 | 从专辑/歌单链接拿到曲目清单和音质档位 | 清单分页截断、音质字段缺失 |
| 传输层 | 分块下载、断点续传、并发控制 | 大文件超时、连接中断、并发过高被限速 |
| 落盘层 | 标签写入、封面嵌入、命名、校验 | 非法字符、Unicode 规范化不一致、标签乱码 |
新手最容易忽略的是第四层。大家都盯着“下下来了没有”,但真正决定这套库五年后还能不能用的,是标签和命名。接口层、传输层出了问题你能立刻发现(报错、文件不完整),落盘层出了问题往往是几年后才发现,那时候补救成本极高。
我见过最典型的翻车现场:三千个文件全部命名成01 - xxx.flac这种格式,没有歌手没有专辑,只靠目录名区分,结果某次整理时误操作把目录拍平了,三千首歌全部变成无名氏。这种错误在终端里一条mv命令就能造成,防不住,只能靠命名规范本身把信息冗余写进文件名。
1.3 方案取舍:为什么我没有选那几条看起来更省事的路
先说被我否掉的三条路。
抓网页结构:这是最原始的做法,解析 HTML 拿直链。问题在于网页结构随时会变,而且拿到的往往是你账号实际听的那个档位,未必是最高档。维护成本高到离谱,一次改版就得改代码。
用现成 GUI 客户端自带的导出:稳定性不错,但导出规则固定死,目录结构改不了,命名模板改不了,多值标签支持也经常不全。对一个准备长期维护曲库的人来说,这等于把标准交给别人定。
自己从零写:我试过。登录态、分块、续传、标签写入,每一项都不难,但拼起来就是个泥潭,尤其是标签库的兼容性问题(不同容器的字段映射差异)能吃掉你两周时间。这类需求已经被打磨成工具了,重复造轮子没有意义。
最后选的是hires-dl这类成熟命令行工具的路线,理由是:配置文件化(标准可固化)、支持模板化命名(信息冗余写进文件名)、支持断点续传(大批量不重来)、能落日志(失败可追溯)。至于它内部用什么语言写的,其实不影响你的使用,你只需要关注它的参数语义和落盘行为。
注意:这类工具的作用边界必须讲清楚。它接入的是你自己已授权的账号,用于把你有权限访问的内容做本地归档和离线缓存,方便在无网络环境(比如飞机上、通勤地铁里)听自己的库。它不是、也不该被当成绕过授权的工具。任何超出个人已授权范围的使用,都不在本文讨论之内。
2. 核心细节解析:无损音频的链路与关键参数
2.1 FLAC、ALAC 与“高解析”的区别,别被营销词带偏
归档格式这件事,我的立场很明确:除了必须进苹果生态的场景,一律选 FLAC。
FLAC 是开放、免专利、生态最广的无损容器。Windows、Linux、安卓、大部分车载主机、绝大多数播放器软件都原生支持,标签体系用的是 Vorbis comment,支持多值字段、支持内嵌图片、支持 ReplayGain。ALAC 的唯一优势是苹果设备原生,但代价是把库锁进了特定生态——你十年后换个播放器,可能还得转一遍格式。
至于“高解析”这个词,它不是一个格式,而是一组参数的俗称:采样率高于 44.1kHz、或位深高于 16bit。24bit/96kHz 的 FLAC 是常见形态。这里要提醒一句:高解析不等于更好听,它带来的是更大的动态余量和更低的量化噪声底,是否听得出差别,跟母带、回放设备、你的耳朵强相关。我个人的做法是“能拿最高档就拿最高档”,理由是存档要存上限,回放时想降到 16/44.1 随时可以转,反过来不行。
要避开的一个坑是假高解析:把 16/44.1 的源上采样到 24/96 再卖。这种文件体积翻三倍,信息量一分没多。判断方法看频谱——真高解析在高频段有实际内容延伸,上采样的文件在 22kHz 附近会有一条明显的断崖(CD 采样率的上限)。工具帮你下载,但判断真伪得自己做。
2.2 采样率、位深与文件体积:把账算清楚再动手
这是最多人问的问题:一张专辑到底占多少空间?我给你一个可以直接套用的算法。
未压缩码率 = 采样率 × 位深 × 声道数。以 44.1kHz/16bit/立体声为例:44100 × 16 × 2 = 1,411,200 bps。FLAC 的实际压缩率通常在 55%~65% 之间(跟音乐复杂度有关,安静的古典乐压缩率高,密集的电子乐压缩率低),取 60% 折算,实际码率约 850 kbps。
于是:
- 16bit / 44.1kHz:约 850 kbps,每分钟约 6.4 MB,一张 45 分钟专辑约 280 MB
- 24bit / 48kHz:约 1150 kbps,每分钟约 8.6 MB,一张专辑约 390 MB
- 24bit / 96kHz:约 2350 kbps,每分钟约 17.6 MB,一张专辑约 790 MB
- 24bit / 192kHz:约 4700 kbps,每分钟约 35 MB,一张专辑约 1.6 GB
把这个表记住,你就有了容量规划的抓手:一千张 24/96 专辑大约是 800 GB,加上冗余和备份,2TB 起步才比较从容。我见过有人拿一块 500G 的移动硬盘想存“全部收藏”,结果下到一半空间告急,被迫回头把高解析版重下成 CD 规格——这活儿重做一遍非常痛苦,宁可提前规划。
还有一个容易被忽略的成本:小文件数量。一张专辑 12 个曲目,一万张专辑就是 12 万个文件。某些文件系统(尤其是网络存储、老旧的 FAT32 移动盘)在文件数量大了之后,目录遍历会明显变慢。如果你打算用移动硬盘做冷备,尽量用 ext4、exFAT 这类对大目录更友好的格式,别用 FAT32。
2.3 标签与封面:决定你的库五年后还能不能用的关键
这里我要说一句可能不太讨喜的话:音质参数决定你三个月后的体验,标签质量决定你五年后的体验。
标签不规范的库,表现是这样的:播放器里专辑混成一堆、同一张专辑被拆成三份(因为歌手字段写法不同)、曲序全是乱的、封面一片空白、按年份筛选时全是“未知”。这些都是可以避免的。
FLAC 用的是 Vorbis comment,常用字段我列一下:
| 字段 | 用途 | 常见的写法坑 |
|---|---|---|
ARTIST | 曲目艺术家 | 合唱作品写成一长串,导致筛选崩坏 |
ALBUMARTIST | 专辑主艺术家 | 空着不填,播放器会把合辑拆散 |
TITLE | 曲名 | 带了多余的前导空格 |
TRACKNUMBER | 曲序 | 写成1而不是01,排序错乱 |
DISCNUMBER | 碟号 | 多碟专辑缺这个字段,两张碟曲序混一起 |
DATE | 发行日期 | 混用2020、2020-05、2020-05-01三种格式 |
GENRE | 流派 | 中英混杂、大小写不一致 |
ISRC | 国际标准录音代码 | 往往被忽略,但它是做去重的最可靠依据 |
其中ALBUMARTIST和DISCNUMBER是最容易被漏掉、后果最严重的两个。合辑没有ALBUMARTIST,播放器会把十二个不同歌手的歌拆成十二张专辑,看着像灾难。多碟专辑没有DISCNUMBER,两张碟的曲序会撞车,排序结果随机。
封面处理上,我一直建议双轨并存:既嵌入到文件里(picture block),也在专辑目录放一份cover.jpg。只嵌不放的缺点是,某些设备(老车载、部分硬件播放器)不读内嵌图,只扫目录里的图片文件;只放不嵌的缺点是,手机播放器按文件逐个展示时一片空白。两边都做,成本几乎为零。
提示:嵌入封面要控制尺寸。见过有人嵌 3000×3000 的图,一张图 2MB,一张专辑 12 首就白占 24MB。600×600 到 1000×1000、JPEG 质量 85 左右,肉眼几乎看不出差别,体积省一个数量级。
2.4 目录命名:把信息冗余写进路径里
命名规范这件事没有绝对标准,但有一条铁律:路径要能把关键信息完整表达出来,不能依赖“我记得当时怎么放的”。
我在用的模板是这样的:
{artist}/{year} - {album}/{disc:02d}-{track:02d} - {title}.flac真实效果:
某乐队/2019 - 某张专辑/01-01 - 开场曲.flac 某乐队/2019 - 某张专辑/01-02 - 第二首.flac 某乐队/2021 - 另一张专辑/02-01 - 双碟专辑第一首.flac几个设计考量:
{year} - {album}前置年份,是为了让目录在按名称排序时天然按时间轴排列,翻歌手目录时是“从早期到近期”的顺滑体验。
{disc:02d}-{track:02d}用两位补零,是为了让文件在纯字典序下也正确排序。不加补零,10会排在2前面,这是最经典的排序事故。单碟专辑我也建议保留 disc 前缀(统一为01-),这样整个库的结构是同构的,脚本处理时不用写分支判断。
标题里要过滤的字符:/ \ : * ? " < > |这些在部分文件系统上是非法字符,直接用作文件名会报错或者被静默替换成下划线(更糟,因为不报错)。还有前导空格、尾随点号,在 Windows 上会引发奇怪问题。这些都要在模板层过滤掉,别指望下载完再批量改名——一万个文件的重命名脚本调试起来比改模板麻烦得多。
3. 实操过程:从零跑通一条完整流程
3.1 环境准备与依赖清单
我把这套流程跑在 Linux 上,但 Windows(WSL)、macOS 上的路径基本一致。核心依赖就三样:运行时环境、标签工具、校验工具。
# 以 Debian/Ubuntu 系为例 sudo apt update sudo apt install -y ffmpeg flac python3 python3-pip # 验证关键工具可用 ffmpeg -version | head -n 1 flac --versionffmpeg用在两处:一是封面图的缩放和格式转换(下载来的图经常是 PNG 或者超大尺寸),二是后期如果需要做格式转换。flac命令行工具用在标签校验和元数据检查。
工具本体我建议装进虚拟环境,别污染系统 Python:
python3 -m venv ~/.venvs/hires source ~/.venvs/hires/bin/activate pip install --upgrade pip pip install hires-dl # 虚构项目名,实际请按官方说明安装 hires-dl --version用虚拟环境的原因很实在:这类工具依赖的库更新频繁,混装到系统环境里,某天升级一个依赖可能把你别的项目搞崩。我在这上面吃过亏,后来所有 Python 类工具一律隔离。
磁盘准备上再提醒一次:确认目标路径所在的文件系统,并且提前跑一遍空写入测试。尤其是网络挂载的目录(NAS),有时候挂载成功但权限不对,工具跑了一半才报“Permission denied”,前面下的全白费。一条命令就能验证:
dd if=/dev/zero of=/你的归档路径/.write_test bs=1M count=100 && rm /你的归档路径/.write_test3.2 登录态获取与配置固化
这一步是小白的最大门槛,也是安全上最需要注意的地方。原则只有一条:凭证只落在本地,不进版本库,不进截图,不进聊天窗口。
通用的做法是走令牌(token)而非账号密码。工具通常会提供一条交互式初始化命令:
hires-dl auth # 按提示完成浏览器授权,回调后把令牌写入本地配置授权完成后,配置文件一般在~/.config/hires-dl/config.toml这类位置。我建议第一时间做两件事:改权限、做备份。
chmod 600 ~/.config/hires-dl/config.toml cp ~/.config/hires-dl/config.toml ~/.config/hires-dl/config.toml.bak600意味着只有当前用户能读写。多用户机器上不改权限,等于把你的账号访问权限对同机器的其他人开放。这个细节很多人都漏掉。
配置文件里我改动的部分主要是模板和并发:
output_dir = "/mnt/music/archive" filename_template = "{artist}/{year} - {album}/{disc:02d}-{track:02d} - {title}" quality = "hi_res" # 优先最高档 embed_cover = true cover_size = 1000 concurrent_downloads = 4 retries = 3quality这一项,如果你的目标服务有多个档位,选最高档;下载后如果需要低规格,用 ffmpeg 批量转,反向操作(拿低档凑高档)是做不到的,信息丢了就是丢了。
3.3 单曲、专辑、歌单、整库:四种粒度的跑法
工具的命令设计通常按“对象类型”分层,我把四种常用粒度的命令列出来:
# 1. 单曲:拿一个曲目链接归档 hires-dl track "https://该服务地址/track/123456" # 2. 专辑:最常用的粒度 hires-dl album "https://该服务地址/album/abcdef" -o /mnt/music/archive # 3. 歌单 / 收藏夹 hires-dl playlist "https://该服务地址/playlist/xyz789" --skip-existing # 4. 整库:把账号下所有已收藏内容拉一遍 hires-dl favorites --type albums --skip-existing --log ~/logs/hires-$(date +%F).log--skip-existing是我用得最多的参数。它的作用是文件已存在就跳过,这让整库同步变成了幂等操作——你可以放心地反复跑,不会重复下载,也不会覆盖已有文件。长期维护曲库的核心机制就是这个:定期跑全量同步,增量自动补齐。
跑大批量任务前,我强烈建议先做一次“干跑”,把清单落下来看看再动手:
hires-dl favorites --type albums --dry-run --output-list ~/todo.txt wc -l ~/todo.txt head -n 5 ~/todo.txt干跑能看到总量、能提前发现异常(比如某个歌单返回了 0 条,说明权限或者接口有问题),能估算磁盘需求。这一步花三十秒,能省掉后面几小时的返工。
3.4 并发数与限速:把参数算出来,别凭感觉填
concurrent_downloads这个参数,新手容易走向两个极端:填 1(慢得怀疑人生)或者填 32(疯狂超时重试)。正确做法是算。
先明确单文件下载时间:文件大小 ÷ 带宽。假设你的下行带宽是 100 Mbps(约 12.5 MB/s),一个 24/96 的曲目平均 60 MB,单文件理论耗时约 4.8 秒。考虑到协议开销和服务器侧波动,实际按 7 秒估。
再看瓶颈。并发的作用是填满“等待时间”——当一个连接在等服务器响应或网络往返时,另一个连接可以传输数据。所以并发数的经验值是理论带宽 / 单连接实际吞吐。单连接实际吞吐往往只有理论值的 40%~70%(取决于网络质量和服务端限制),取 50%,则 100 Mbps 带宽下单连接约 6 MB/s,需要 2 个连接就能跑满。留点余量,设 3~4 最稳。
再加一层约束:服务端通常有频率限制。并发调太高,你会开始看到 429 或者连接被重置。判断方法很简单——把并发从 4 提到 8,如果平均耗时反而上升、失败率上升,说明触发了限速,回退到 4。这个拐点每个服务、每个时段都不一样,只能实测。
# 用日志里的时间戳做对比,比凭感觉靠谱 grep -c "retry" ~/logs/hires-*.log注意:真正的瓶颈经常不在你的带宽,而在磁盘写入。尤其是往机械硬盘或者网络存储写大量小文件,并发 8 时磁盘可能先扛不住,表现为下载完成但落盘缓慢。遇到这种情况,降并发比升并发有效。
3.5 断点续传与完整性校验
大批量任务最怕的不是慢,是断。跑了两千首,网络抖了一下,进程挂了,如果工具不支持续传,你得从头再来一遍——即使有--skip-existing,也要重新走一遍清单解析和请求,时间成本不低。
先确认续传能力:
hires-dl album "https://该服务地址/album/abcdef" --resume续传的原理通常是写临时文件(.part后缀)加偏移量记录,中断后从中断位置继续。这里有个隐蔽的坑:如果工具在写临时文件时被强制杀掉(kill -9),偏移量记录可能没来得及刷盘,续传会从一个错误的偏移开始,产出损坏文件。所以我的做法是:正常中断用Ctrl+C(发 SIGINT,让程序有机会收尾),不要用kill -9。真的被强杀了,那个.part文件直接删掉重下,别赌。
落盘后做校验。理想情况是服务端提供文件哈希,逐文件比对;实际情况往往没有,那就退一步做结构性校验:
# 用 flac 自带工具做完整性检查,能发现截断和损坏 find /mnt/music/archive -name "*.flac" -print0 | xargs -0 -n 1 flac -t 2>&1 | grep -v "ok$" # 统计文件数与总大小,跟干跑清单做对比 find /mnt/music/archive -name "*.flac" | wc -l du -sh /mnt/music/archiveflac -t会真正解码一遍做校验,速度不慢(现代 CPU 上比实时快几十倍),两千首大概几分钟跑完。这个检查我建议每季度做一次,能提前发现磁盘坏块导致的静默损坏。硬盘坏了不可怕,可怕的是坏了半年你才发现,那时候原始文件也未必还在。
4. 常见问题与排查技巧实录
4.1 症状、原因、处置:一张能直接查的表
下面这张表是我在实际操作中攒出来的,覆盖了九成以上的问题。遇到报错先别急着搜,对着表定位往往更快。
| 症状 | 最可能的原因 | 处置办法 |
|---|---|---|
| 登录后立刻提示“未授权/令牌无效” | 令牌过期,或被其他设备的登录挤掉 | 重新执行auth流程,重新写入配置 |
| 清单只拿到前 25 条 | 分页参数没生效,或接口限制了单次返回量 | 加--all-pages,或分批按歌单跑 |
| 大量 429 / 连接重置 | 并发过高触发频率限制 | 并发降到 2~3,加重试退避间隔 |
| 文件下完了但大小明显偏小 | 传输中断未正确续传,写出了截断文件 | 删掉该文件重下,禁用kill -9 |
| 文件名里出现下划线替换 | 模板中的非法字符被静默处理 | 在模板层加过滤规则,别等落盘后改名 |
| 播放器里专辑被拆成多张 | 缺ALBUMARTIST,或写法不统一 | 批量补齐ALBUMARTIST,统一大小写 |
| 曲序错乱(10 排在 2 前面) | 曲序未补零,或DISCNUMBER缺失 | 模板加:02d,多碟专辑补 disc 字段 |
| macOS 上中文文件名显示异常 | Unicode 规范化形式不一致(NFC/NFD) | 统一转换到 NFC,别混用 |
| 封面不显示 | 只嵌入了内嵌图,设备不读 | 同时放一份cover.jpg到专辑目录 |
| 空间突然不够 | 高解析档位体积远超预期 | 按 2.2 节的公式提前核算 |
4.2 几个反直觉的坑,希望你别重复踩
坑一:以为“下载成功”就等于“文件正确”。工具打印完成,不代表文件完整。传输层可能在最后一秒出问题,程序认为写完了,实际字节数少了几 KB。这种文件的特征是时长正常但结尾有爆音,或者flac -t报错。所以校验必须独立于下载流程之外做,别信进度条。
坑二:在同一个目录里混用两种命名模板。我早期干过这事:先按“歌手/专辑/曲目”存了一批,后来觉得“年份前置”更好,改了模板接着跑。结果同一个歌手目录下两套结构并存,排序全乱,后来花了一个通宵写脚本统一。改模板之前,先想清楚要不要全库重命名;要改就一次性改到位,别新旧混存。
坑三:忽略多值标签。一首歌有两个艺术家,有些写入方式会存成两个独立的ARTIST字段(正确),有些会拼成一个字符串“A; B”或“A feat. B”(错误)。后者在按艺术家筛选时会出现一堆“A feat. B”这种非标准条目。写入前确认工具的行为,必要时用metaflac检查:
metaflac --list --block-type=VORBIS_COMMENT 某个文件.flac | grep -A1 ARTIST坑四:拿生产目录做实验。想试新参数、新模板,在几百 GB 的真实曲库上直接跑,出了问题很难回滚。我的做法是建一个~/sandbox目录,固定放五张专辑做实验田,任何新配置先在这里跑通、检查命名和标签都对了,再放到正式目录。这习惯救过我好几次。
坑五:没留意服务的档位命名差异。不同服务对“无损”和“高解析”的叫法不一样,配置里那个quality值填错了,工具可能安静地退回到默认档位,你下了一千首以为是 24/96,实际全是 16/44.1。跑之前先拿三首做抽样验证:
# 检查实际采样率和位深,别信文件名 ffprobe -v error -select_streams a:0 \ -show_entries stream=sample_rate,bits_per_raw_sample,channels \ -of default=noprint_wrappers=1 某个文件.flac4.3 批量任务的三段式跑法
踩了这么多坑之后,我把所有大批量任务的跑法固定成三段,现在基本不再出意外。
第一段是清单段:只解析、不下载,把待办清单落成文件,人工扫一眼总量和前几条。这一步能拦住“链接填错”“歌单是空的”“权限不够只返回了部分”这类问题。
第二段是样本段:从清单里抽 5 条真实下载,检查文件大小、采样率、标签、封面、命名五个维度。这一步拦的是配置类问题。
第三段才是全量段:加--skip-existing、挂日志、放后台跑。跑的时候我不盯着,但会定期看两个数:已完成数和失败数。失败数超过总量 3%,就停下来查,别硬跑完——失败往往是系统性的,硬跑只会积压更多垃圾文件。
5. 我的实操心得:曲库长期维护的几条规矩
5.1 把“一次性下载”变成“可运营的库”
很多人把归档当成一次性动作,下完就扔在那儿。我的观察是,真正有价值的不是下载动作,是后续三年的维护机制。三条规矩,都是吃过亏换来的。
第一条,固定模板,永不轻易改。模板一旦定下来就是契约,全库结构以它为准。真要改,先写一个覆盖全库的迁移脚本,在一份副本上跑通、校验无误,再动生产目录。我现在的做法是把模板写进配置文件并加注释标注“改动需全库迁移”,给自己一个刹车。
第二条,用 ISRC 做去重依据,而不是文件名。同一首歌可能来自专辑版、单曲版、精选集、现场版,文件名各不相同,但 ISRC 是唯一的。库里同一 ISRC 出现多次,大概率是重复归档;不同 ISRC 才是真正的不同版本(比如录音室版和现场版 ISRC 通常不同)。用一条命令就能扫出来:
find /mnt/music/archive -name "*.flac" -print0 \ | xargs -0 -n 1 metaflac --show-tag=ISRC \ | sort | uniq -d第三条,日志永久保留。每次跑批都往~/logs/写一份带日期的日志,不清理。日志的价值在于回溯——某张专辑标签不对,你能查到是哪个批次、什么时候、用什么参数下的。没有日志,你只能猜。日志文件很小,一年也就几 MB,没必要省。
5.2 备份策略:3-2-1 落到曲库上的具体做法
曲库最怕的不是硬盘坏,是“坏了才发现另一份备份也有问题”。我的做法是 3-2-1 原则的具体化:三份数据、两种介质、一份异地。
第一份是工作盘(SSD 或本地机械盘),日常读写用。第二份是本地冷备盘,每月同步一次,平时不通电,避免同时损坏。第三份是异地,可以是另一处的机器,也可以是定期的离线介质,看你的条件。关键是异地那份要有独立的校验记录,不能只是“拷过去了”。
校验这块我做两件事。一是每月对工作盘做一次flac -t全量检查,记录失败清单。二是每季度对冷备盘做一次抽样解码(随机抽 5%,跑flac -t),确认备份介质本身没坏。抽样比例不高,但能覆盖到大部分坏块区域。
# 随机抽 5% 做解码校验,适合冷备盘 find /mnt/backup/archive -name "*.flac" | shuf -n $(( $(find /mnt/backup/archive -name "*.flac" | wc -l) / 20 )) \ | xargs -n 1 flac -t 2>&1 | grep -v "ok$"同步用rsync而不是直接复制,关键是--checksum参数:
rsync -av --checksum --delete-after \ /mnt/music/archive/ /mnt/backup/archive/ \ --log-file=~/logs/rsync-$(date +%F).log--checksum会让 rsync 比对文件内容而不是依赖时间戳和大小。慢一些,但能捕获“大小和时间都对、内容坏了”这种静默损坏,对长期存档来说值得。--delete-after是为了让删除操作在传输完成后再执行,避免中途出错导致备份被清空——这个顺序很关键,反了就是灾难。
最后分享一个我用了很久的小习惯:在新一批归档完成后,立刻把那一批的“清单 + 日志 + 校验结果”打包成一个小的文本档案,跟曲库一起存。三年后你打开它,能完整还原这批文件是何时、以什么参数、从什么来源拿到的。这东西占不了几 MB,但当你需要证明某个文件的来源,或者需要复现一次特定的归档时,它就是唯一可靠的凭证。
这套东西跑顺了之后,日常维护成本极低——每月找个时间,跑一次全量同步、一次校验、一次 rsync,全程不用盯,看日志就行。真正花时间的是前面把配置、模板、校验流程都打磨对的那几天。那几天值得花,因为它决定了你这个库是一堆散落文件,还是一个能长期用下去的曲库。