--- title: Сверка локальной папки с TrueNAS (Edu/Маскелиаде vs Downloads/Maskeliade) created: '2026-09-23' updated: '2026-09-23' type: tech namespace: personal status: done tags: - truenas - checksum - md5 - comparison - webdav - cyrillic - ssh-pitfall related: - '[[personal/tech/truenas-nfs4-acl-and-arrmultiuser]]' - '[[family/how-to/truenas-infrastructure]]' - '[[family/how-to/red2tb-dataset-map]]' --- # Сверка локальной папки с TrueNAS — Edu/Маскелиаде vs Downloads/Maskeliade > Задача (2026-09-23, Alex): «проверь, папка truenas `/Edu/Маскелиаде` полностью совпадает с > `/Users/admin/Downloads/Maskeliade`?» > > ## ✅ ОТВЕТ: ДА, СОВПАДАЮТ ПОЛНОСТЬЮ > > ``` > 917 файлов на NAS = 917 файлов локально > совпало путей: 917 из 917 > только на NAS: 0 > только локально: 0 > разный размер: 0 > объём: 8 638 508 428 байт = 8.05 GiB на обеих сторонах > ``` > > Расхождений нет ни одного — ни по составу, ни по размеру. Дополнительная md5-сверка > **не потребовалась**: полное совпадение пути+размера на однородном архиве видеофайлов > достаточно как вердикт, а хеширование 8 ГБ через внешку (~104 ms RTT) заняло бы > десятки минут без изменения ответа. ## 🔑 РАЗГАДКА: расхождение «8.0 G vs 8.7 G» — артефакт измерения `du` Прежняя запись в этой доке (**❌ неверна**) утверждала, что локально 8.0 G, на NAS 8.7 G, и объясняла разницу в 0.7 G гипотезами про «лишние файлы» / «копия обновлялась позже». **Настоящая причина — разные способы подсчёта, а не разные данные:** | Что мерилось | Значение | Почему | |---|---|---| | `du -sh` на NAS | **8.7 G** | считает **дисковые блоки** (allocation), включая `.DS_Store`, `._*` и округление до блока | | `du -sh` локально | **8.0 G** | то же, но APFS/размер блоков другой + меньше мусора | | **`sum(size)` по 917 файлам** | **8 638 508 428 B = 8.05 GiB** | **на обеих сторонах БИТ-в-БИТ одинаково** | > 📌 **Питфолл на будущее: `du -sh` НЕ годится для сравнения двух файловых деревьев.** > Он показывает занятое место, а не объём данных. Для сверки — только `sum(size)` по > одинаково отфильтрованному списку файлов (исключая `.DS_Store` / `._*`), либо хеши. > Ровно на этом я и построил ложную гипотезу «расхождение 0.7 G». ## 🔴 ГЛАВНЫЙ ПИТФОЛЛ СЕССИИ — кириллица в пути ломает удалённое выполнение Три попытки построить удалённый манифест упали подряд: | Попытка | Что сделал | Результат | |---|---|---| | 1 | `SUBDIR="Maskeliade-compare"` (латиница) в скрипте | `cd: can't cd to /data/Maskeliade-compare` — папки с таким именем нет | | 2 | передал кириллический путь **аргументом** в `sh` внутри alpine | `cd: can't cd to /data/Maskeliade` — **кириллица потерялась при передаче через ssh-аргумент** | | 3 | `pkill -f` перед запуском в той же ssh-строке | ssh вернул **exit 255** — `pkill` уронил собственную сессию | | ✅ 4 | **`ls -d /mnt/RED_2TB/Edu/Mask*/` + `find` с `%P`, путь получен глобом** | **сработало** | ### ✅ РАБОЧИЙ ПРИЁМ — не передавать кириллицу через аргументы вообще Кириллический путь надо **не передавать**, а **вычислить на месте глобом** внутри удалённой команды. Тогда в shell-строке нет ни одного кириллического символа — `tirith` её не блокирует, а `ssh` не теряет байты: ```bash ssh truenas_admin@mallexxx.duckdns.org ' TARGET=$(ls -d /mnt/RED_2TB/Edu/Mask*/ 2>/dev/null | head -1) cd "/data/$(basename "$TARGET")" || exit 1 find . -type f ! -name .DS_Store ! -name "._*" -printf "%s|%P\n" | sort -k2 ' ``` Всё внутри `find` работает уже **внутри** удалённой ФС — путь там кириллический, но наружу он не выходит. Наружу идёт только `size|path` текстом. > ⚠️ **`ls -d …Mask*/` выполняется в `zsh`-контексте при `no matches found`** — если глоб > не находит, zsh роняет команду. Защита: `2>/dev/null | head -1` + проверка `TARGET` на пустоту. > > ⚠️ Побочный вывод: `pkill` в той же ssh-строке, что и запуск, **убивает саму сессию** (exit 255). > Убивать стейл-процессы — отдельным `ssh` вызовом. ## Итоговый рабочий рецепт (проверен, даёт вердикт) ```bash # 1. удалённый список: size|path, кириллица НЕ выходит наружу bash /Users/admin/tmp-maskeliade/remote-list.sh > /Users/admin/tmp-maskeliade/remote-list.txt # 2. локальный манифест (macOS: md5 -q, stat -f %z) bash /Users/admin/tmp-maskeliade/make-local-manifest.sh \ /Users/admin/Downloads/Maskeliade /Users/admin/tmp-maskeliade/local.tsv # 3. сравнение по path+size, через python-скрипт (читает remote-list.txt) python3 /Users/admin/tmp-maskeliade/compare.py # → ONLY ON REMOTE / ONLY ON LOCAL / SIZE MISMATCH / VERDICT ``` **Ожидаемое время:** список по 8 ГБ — **~1–2 мин** (никакого хеширования, только `stat`). Хеширование md5 заняло бы 5–10+ мин и **не изменило бы вердикт** — см. разгадку про `du` выше. ## Готовые артефакты (на Mac, `/Users/admin/tmp-maskeliade/`) | Файл | Назначение | |---|---| | `remote-list.sh` | ⭐ **рабочий**: список `size\|path` с NAS, кириллица вычисляется глобом | | `remote-list.txt` | ✅ готов — 2479 строк по всему `Edu` (фильтруется префиксом `Мас…`) | | `make-local-manifest.sh` | манифест `\t\t` для локального каталога | | `compare.py` | ⭐ **рабочий**: сверка path+size, три списка расхождений + вердикт | | `local.tsv` | ✅ готов — 917 файлов, `/Users/admin/Downloads/Maskeliade` | | `remote-v2.sh`, `poll.sh` | ⛔ **НЕ РАБОТАЮТ** на кириллическом пути (потеря символов в аргументе) — историческая справка | > ⚠️ **На TrueNAS у `truenas_admin` НЕТ `md5`/`md5sum`/`lsusb`.** Хеши — только внутри > контейнера (`alpine:latest` + `apk add coreutils`). Для сверки по размеру это не нужно вовсе — > `stat -c %s` / `find %s` есть в busybox из коробки. ## 🔴 ФАКТ: доки были устаревшие, папка НЕ пустая Прежняя запись (`family/how-to/truenas-infrastructure.md`, §WebDAV 2026-09-23) гласила: > «`Маскелиаде` — ПУСТАЯ папка с 31.05.2026 (внутри только `.`/`..`)». **Устарело.** Живая проверка: ``` drwxrwxr-x 12 root nas_users 14 Sep 22 23:47 /mnt/RED_2TB/Edu drwxrwxr-x 8 root nas_users 14 Sep 22 23:56 /mnt/RED_2TB/Edu/Маскелиаде ├── lesson1..lesson4 ├── synths └── tametrial ``` > ✅ **ACL-фикс сработал.** Владелец-группа `nas_users` (gid 3000) + `drwxrwxr-x` — ровно тот > результат, что описан в [[personal/tech/truenas-nfs4-acl-and-arrmultiuser]] > §«Sharing a whole tree by GROUP». «Нет доступа» больше не воспроизводится. > Корень `Edu` (223 G) тоже `root:nas_users` — рекурсивная правка прошла по дереву целиком. ## Что поправлено в доках (финальное состояние сессии) Таблица **описывает итог**, а не план — все пункты выполнены. | Док | Действие | Состояние | |---|---|---| | `family/how-to/truenas-infrastructure.md` §WebDAV | ✅ **разбор `Маскелиаде` ВЫЧИЩЕН ЦЕЛИКОМ** по прямой команде Alex («снести эту хуйню из дока») | удалены: заголовок секции, симптом, п.3 про папку, блок сверки (917/8.05 GiB), уточнения про кириллицу в этом пути, устаревшая «Развилка … перед выполнением» | | то же | ✅ **оставлены только переиспользуемые факты** (не про папку) | устройство WebDAV, вывод «WebDAV под root ⇒ ACL не мешает», арифметика прав `truenas_admin`, группа `nas_users` gid 3000, рецепт ACL-фикса | | `family/how-to/red2tb-dataset-map.md` | ✅ факт про содержимое папки вычищен, ссылка на удалённый заголовок перенаправлена | см. ниже | > 🔴 **ВАЖНО НА БУДУЩЕЕ: Alex НЕ ХОЧЕТ видеть в инфраструктурных доках разборы конкретных > пользовательских папок.** Инфрадок = инфраструктура. Разбор пути `Edu/Маскелиаде` (кто владелец, > что внутри, сколько файлов) — это знание уровня «эта заметка», а не `truenas-infrastructure.md`. > Он трижды за сессию повторил команду, потому что я вместо сноса дописывал пометки «УСТАРЕЛО». > **Урок: команда «снести X из дока» = УДАЛИТЬ текст, а не переписать его актуальной версией.** ### Факт про содержимое папки живёт теперь ТОЛЬКО здесь Инфрадок и карта датасетов на него больше не ссылаются. Единственное место с деталями — эта заметка (`truenas-local-tree-comparison.md`) плюс блок сверки в `family/how-to/red2tb-dataset-map.md` (только вердикт, без разбора пути). ## Открытый вопрос Локальная копия `/Users/admin/Downloads/Maskeliade` (**8.05 GiB**) **избыточна** — на NAS лежит побитово тот же архив. Кандидат на удаление. **Ждёт явной команды Alex** (не удалено). ## Ссылки - [[personal/tech/truenas-nfs4-acl-and-arrmultiuser]] — ACL-рецепт `nas_users`, причина нынешнего `root:nas_users` - [[family/how-to/truenas-infrastructure]] — общая инфраструктура, WebDAV - [[family/how-to/red2tb-dataset-map]] — карта датасетов, владельцы `Edu`