it-swarm-eu.dev

Rekurzivně porovnávat dva adresáře s diff -r bez výstupu na přerušené odkazy

Používám diff -r a b pro rekurzivní porovnání adresářů a a b. Často se však stává, že existují některé přerušené odkazy (stejné přerušené odkazy v adresářích a a b a směřující ke stejným neexistujícím cílům).

diff pak vydá chybové zprávy pro tyto případy a skončí s nenulovým výstupním kódem, ale rád bych, aby zůstal tichý, a skončil s 0, protože adresáře jsou stejné v mé knize.

Jak to mohu udělat?

44

Pro verzi 3.3 nebo novější verze diff byste měli použít znak --no-dereference možnost, jak je popsáno v odpověď Pete Harlana .

Bohužel, starší verze diffnepodporují ignorování symlinks :

Některé soubory nejsou ani adresáři ani běžnými soubory: jedná se o neobvyklé soubory, jako jsou symbolické odkazy, speciální soubory zařízení, pojmenované kanály a zásuvky. V současné době diff zachází se symbolickými odkazy, jako jsou běžné soubory; zachází s jinými speciálními soubory, jako jsou běžné soubory, jsou-li určeny na nejvyšší úrovni, ale při porovnávání adresářů jednoduše hlásí jejich přítomnost. To znamená, že patch nemůže představovat změny takových souborů. Pokud například změníte, na který soubor symbolický odkaz odkazuje, diff vydá rozdíl mezi dvěma soubory namísto změny na symbolický odkaz.

diff by měl volitelně hlásit změny speciálních souborů a patch by měl být rozšířen, aby porozuměl těmto příponám.

Pokud chcete pouze ověřit rsync (a pravděpodobně opravit, co chybí), můžete spustit příkaz rsync podruhé. Pokud to nechcete dělat, pak může stačit check-sumizing directory .

Pokud to opravdu chcete dělat s diff, můžete pomocí find přeskočit symbolické odkazy a spustit rozdíl v každém souboru samostatně. Jako argumenty předejte své adresáře a a b :

#!/bin/bash
# Skip files in $1 which are symlinks
for f in `find $1/* ! -type l`
do
    # Suppress details of differences
    diff -rq $f $2/${f##*/}
done

nebo jako jednodílný:

for f in `find a/* ! -type l`;do diff -rq $f b/${f##*/};done

To bude identifikovat soubory, které se liší obsahem, nebo soubory, které jsou v a , ale nikoli v b .

Všimněte si, že:

  • protože přeskočíme celé odkazy, nebude to patrné, pokud názvy symbolických odkazů nejsou v b . Pokud jste to požadovali, budete potřebovat druhý průkaz pro nalezení všech symbolických odkazů a pak explicitně zkontrolovat jejich existenci v b .
  • Extra soubory v b nebudou identifikovány, protože seznam je sestaven z obsahu a . Toto pravděpodobně není problém pro váš scénář rsync.
29
ire_and_curses

Od verze 3.3 GNU diff nepodporuje dereferenční symlinks, ale porovnává cesty, na které poukazují).

Nainstalujte GNU diffutils> = 3.3 a použijte --no-dereference volba; neexistuje žádná krátká možnost.

Diagnostika bude zticha, pokud bude stejná nebo:

Symbolické odkazy /tmp/noderef/a/symlink a /tmp/noderef/b/symlink lišit

21

Můžete použít novější verzi diff

diff in GNU diffutils 3.3 obsahuje --no-dereference možnost, která vám umožní porovnat samotné odkazy spíše než jejich cíle. Hlášení, pokud se liší, je tiché, pokud se shodnou a nezajímá, zda jsou zlomené.

Nevím, kdy byla tato možnost přidána; není přítomen v 2.8.1.

6
Pete Harlan