Files
obsidian-vault/personal/tech/truenas-local-tree-comparison.md
T
Taiga b53dd70a15 [2026-09-26 09:10:28] syncthing: personal/tech/archive-org-collection-harvest.md personal/tech/balda-go-fx-pitfalls.md personal/tech/bilety-oxota-interaktiv.md personal/tech/cloudflare-tunnel-ssh-published-route.md personal/tech/deepseek-language-drift.md personal/tech/docker-data-root-mount-race.md personal/tech/docker-mac-disk-issues.md personal/tech/docker_colima_setup.md personal/tech/eagle-dashboard-launchd.md personal/tech/hermes-agent-improvements.md personal/tech/hermes-browser-toolsets.md personal/tech/hermes-fork-vs-upstream.md personal/tech/hermes-git-repo.md personal/tech/hermes-memory-architecture.md personal/tech/hermes-secret-redaction-bypass.md personal/tech/hermes-self-improvement-review.md personal/tech/home-network-config.md personal/tech/inter-site-throughput-taiga-to-mac.md personal/tech/inter-site-throughput-taiga-to-mac.md.bak-nedstab2 personal/tech/jellyfin-db-schema-mismatch.md personal/tech/karabiner-keyboard-config.md personal/tech/kraken-media-inventory-facts.md personal/tech/kraken-truenas-media-copies.md personal/tech/lampa-jellyfin-plugin.md personal/tech/lampac-deployment.md personal/tech/lampac-torrserver.md personal/tech/llm-model-selection-2026.md personal/tech/mac-print-shared-services.md personal/tech/modbus-rtu-sniffer-debugging.md personal/tech/multistream-single-flow-limit.md personal/tech/multistream-single-flow-limit.md.bak-nedstab2 personal/tech/music-tags-repair-truenas.md personal/tech/obsidian-mcp-ecosystem.md personal/tech/original-xbox-2025-guide.md personal/tech/prowlarr-flaresolverr-cloudflare.md personal/tech/radarr-sonarr-phantom-records.md personal/tech/roundtrip-key-verification.md personal/tech/ryujinx-mac-setup.md personal/tech/skill-arr-media-stack-setup-additions.md personal/tech/skill-docker-data-root-mount-race.md personal/tech/skill-lampac-kraken-deploy.md personal/tech/tirith-trust.md personal/tech/truenas-local-tree-comparison.md personal/tech/truenas-nfs4-acl-and-arrmultiuser.md personal/tech/truenas-zfs-panic-recovery.md personal/tech/vault-doc-pruning.md personal/tech/vless-space-subscription-egress.md personal/tech/watchlist-sync-feed.md personal/tech/watchtower-docker-updates.md personal/tech/xray-outbound-subscription-3xui.md personal/tech/xray-reverse-limits-private-network.md personal/tech/xray-reverse-tunnel-kraken-truenas.md personal/tech/xray-reverse-tunnel-kraken-truenas.md.bak-nedstab2 personal/tech/yandex-music-api.md
2026-09-26 09:10:28 +00:00

179 lines
12 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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` | манифест `<path>\t<size>\t<md5>` для локального каталога |
| `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`