Portál AbcLinuxu, 25. října 2025 21:39
Resim nasledujici - mam hlavni adresar v kterém jsou podadresare do 3-4 urovne. V techto adresarich jsou mkv, ktere budou po rsyncu na sekundarnim storage konvertovany na mp4. Vzhledem k tomu, ze rsync se bude z hlavniho na sekundarni storage v pravidelne opakovat, protoze nove soubory neustale pribyvaji, hledam jak provest opakovany rsync tak, aby se nahraly pouze nove mkv a ne originalne rsyncovane, aktualne uz na sekundarnim storage prejmenovane na mp4. Jak na to?
ssh sekundární "ls -lr" > tmp1, ls -lr > tmp2, ... | sed -re "s/mp4/mkv/" | ..., comm -3 tmp1 tmp2).
Předpokládám, že na cílovém disku se mají původní .mkv po konverzi na .mp4 smazat, jinak by celá otázka měla velmi triviální řešení (nemazat).
Inu, tady mě napadá ošklivé, prasácké, ale účinné řešení založené na rsync: Místo mazání původní .mkv ponechat na místě, ale zmenšit je (například pomocí truncate) na nulu a obnovit jejich původní datum změny. Pak si rsync bude myslet, že už tam jsou, ale zároveň nebudou zabírat místo. Při konverzi do .mp4 je pak potřeba odfiltrovat ty .mkv, které mají nulovou velikost. Problém tohoto postupu: bitrot — Tedy nelze použít rsync -c (ze zjevných důvodů) a není tam vůbec žádná „end to end“ ochrana proti silent data corruption. Ale pokud jde jen a pouze o to „přeskočit“ už zpracované soubory, tohle by mohlo fungovat.
Gah. No to se mi povedlo, tahle↑ „rada“. Tohle je problém:
rsync finds files that need to be transferred using a "quick check" algorithm (by default) that looks for files that have changed in size or in last-modified time.
Dobře, tak úplně jednoduše a „implicitně“ to nepůjde. Existuje sice --size-only, ale není tam žádný ekvivalent --time-only, který by pomohl v tomto případě.
Takže podle mě by mohlo být řešením --ignore-existing (skip updating files that exist on receiver). To vypadá, že by to mohlo (správně) přeskočit přenos již zpracovaných .mkv souborů — pokud na cíli budou ponechané ty placeholdery zmenšené na nulu (kvůli úspoře místa).
#!/bin/bash
# Directory to watch for new MKV files
WATCH_DIR="/path/to/watch"
# Loop to keep checking for new MKV files
inotifywait -m -e create --format "%f" "$WATCH_DIR" | while read NEW_FILE
do
# Check if the new file is an MKV file
if [[ "$NEW_FILE" =~ \.mkv$ ]]; then
# Full path to the new MKV file
MKV_FILE="$WATCH_DIR/$NEW_FILE"
# Full path to the target MP4 file
MP4_FILE="${MKV_FILE%.mkv}.mp4"
# Convert the MKV file to MP4 using ffmpeg
ffmpeg -i "$MKV_FILE" -codec:v libx264 -codec:a aac -strict experimental "$MP4_FILE"
# Check if conversion was successful
if [[ $? -eq 0 ]]; then
# Remove the original MKV file after successful conversion
rm "$MKV_FILE"
echo "Converted and removed $MKV_FILE"
else
echo "Error converting $MKV_FILE"
fi
fi
done
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.