Caldo per fare in modo che diff controlli un link simbolico stesso?


8

In Linux è possibile utilizzare il comando diffper verificare le differenze di file. Lo uso per verificare le differenze tra due moduli, entrambi copiati /tmp.

Tuttavia, entrambi i moduli hanno collegamenti simbolici, che potrebbero non puntare al file corretto, poiché i moduli sono stati copiati nella /tmpdirectory. Ma questo non importa. Quello che voglio controllare è se i symlink sono gli stessi.

Ad esempio, in un modulo legge il link simbolico

/home/test/file1

e nell'altro il link simbolico recita:

/etc/rc.d/whatever

diffora genera un errore perché - in generale - non riesce a trovare il file. Ma voglio diffdire: "Ehi, quei collegamenti simbolici non sono gli stessi" indipendentemente dal fatto che i collegamenti puntino a file validi o meno.

Domanda: Come è possibile difffarlo, cioè non cercare di seguire i collegamenti, ma differli?

Risposte:


6

Prova GNU diffversione 3.3 o successive con l' --no-dereferenceopzione (e presumibilmente l'opzione --recursive):

diff --recursive --no-dereference tree1root tree2root

Potresti arricchire un po 'questo? Forse fai un esempio di come potrebbe essere usato? Questo ha i presupposti per una risposta perfettamente valida, ma ci piace che le nostre risposte siano un po 'più esplicite e dettagliate qui.
terdon

3

Dalla versione 3.3, GNU diff supporta il non-dereferenziamento dei collegamenti simbolici, ma confronta i percorsi a cui puntano.

Installa GNU diffutils> = 3.3 e usa l'opzione '--no-dereference'; non esiste un'opzione breve per quello.

La diagnostica sarà silenziosa se i percorsi sono uguali o:

Symbolic links /tmp/noderef/a/symlink and /tmp/noderef/b/symlink differ

se i percorsi differiscono.


1

Con gli strumenti GNU:

diff <(cd dir1 && find . -type l -printf '%p -> %l\n'|sort) \
     <(cd dir2 && find . -type l -printf '%p -> %l\n'|sort)

A rigor di termini, ciò non può distinguere tra un link simbolico chiamato ache punta a b -> ce uno chiamato a -> bche punta a c, per non parlare dei problemi con nomi di file contenenti caratteri di nuova riga, ma ciò rende un output più leggibile rispetto al più robusto:

diff <(cd dir1 && find . -type l -printf '%p // %l\0'|tr '\n\0' '\0\n'|sort) \
     <(cd dir2 && find . -type l -printf '%p // %l\0'|tr '\n\0' '\0\n'|sort)

Lì, usiamo //come separatore (che non può verificarsi altrimenti nell'output di findfor %p) e convertiamo i caratteri di nuova riga in caratteri NUL (che non possono verificarsi nell'espansione di %p%l).


1

Se ho capito bene, si desidera verificare che i collegamenti simbolici puntino alla stessa destinazione teorica o che se uno non è un collegamento simbolico, l'altro file si collega allo stesso file. Questo dovrebbe fare quello che vuoi:

#!/bin/bash

if [[ "$(readlink -m -- "$1")" == "$(readlink -m -- "$2")" ]]; then
    echo "files match"
else
    echo "files don't match"
    exit 1
fi
$ > foo 
$ ln -s foo bar
$ ln -s foo baz
$ ./script bar baz
files match
$ ./script bar foo
files match
$ ln -sf qux bar
$ ./script bar foo
files don't match

@StephaneChazelas Questo è il mio errore, intendevo usare -m, no -f. Grazie!
Chris Down,

A rigor di termini, ciò non funzionerebbe se l'unica differenza fosse il numero di caratteri newline finali negli obiettivi dei collegamenti simbolici.
Stéphane Chazelas,

Non userei -mneanche.
Stéphane Chazelas,

@StephaneChazelas Per quale motivo? Senza di esso, i collegamenti simbolici relativi che puntano davvero allo stesso file non riusciranno a fare questo confronto.
Chris Down,

Se /home/test/file1è un collegamento simbolico /etc/rc.d/whatevero entrambi sono un collegamento simbolico /, segnalerebbe che sono uguali. Penso che l'OP voglia vedere la differenza nel "percorso" memorizzato nel collegamento simbolico, non se si risolvono nello stesso file (per il quale hai [[ a -ef b ]]).
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.