Hot untuk membuat berbeda memeriksa tautan symlink itu sendiri?

8

Di Linux seseorang dapat menggunakan perintah diffuntuk memeriksa perbedaan file. Saya menggunakannya untuk memeriksa perbedaan di dua modul, keduanya disalin ke /tmp.

Namun, kedua modul memiliki symlink, yang mungkin tidak menunjuk ke file yang benar, karena modul telah disalin ke /tmpdirektori. Tapi ini tidak masalah. Yang ingin saya periksa adalah apakah symlinknya sama.

Misalnya, dalam satu modul symlink membaca

/home/test/file1

dan di symlink yang lain tertulis:

/etc/rc.d/whatever

diffsekarang melempar kesalahan karena - secara umum - tidak dapat menemukan file. Tetapi saya ingin diffmengatakan: "Hai, symlinks itu tidak sama" terlepas dari apakah tautannya menunjuk ke file yang valid atau tidak.

Pertanyaan: Bagaimana mungkin diffmelakukan itu, yaitu tidak mencoba mengikuti tautan, tetapi untuk membedakan tautan itu sendiri?

Alex
sumber

Jawaban:

6

Coba GNU diffversi 3.3 atau yang lebih baru dengan --no-dereferenceopsi (dan mungkin opsi --recursive):

diff --recursive --no-dereference tree1root tree2root
Britton Kerin
sumber
Bisakah Anda menyempurnakan ini sedikit? Mungkin memberi contoh bagaimana itu bisa digunakan? Ini memiliki kemampuan untuk menghasilkan jawaban yang sangat baik tetapi kami ingin jawaban kami menjadi sedikit lebih eksplisit dan bertele-tele di sini.
terdon
3

Sejak versi 3.3, GNU diff tidak mendukung symlink dereferencing, tetapi kemudian membandingkan jalur yang mereka tuju.

Instal GNU diffutils> = 3.3 dan gunakan opsi '--no-dereference'; tidak ada opsi pendek untuk itu.

Diagnostik akan diam jika jalurnya sama, atau:

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

jika jalurnya berbeda.

Philippe De Muyter
sumber
1

Dengan alat GNU:

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

Sebenarnya, itu tidak dapat membedakan antara symlink yang disebut aitu menunjuk ke b -> cdan yang disebut a -> bmenunjuk c, untuk tidak menyebutkan masalah dengan nama file yang mengandung karakter baris baru, tetapi itu membuat untuk output yang lebih terbaca daripada yang lebih kuat:

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)

Di sana, kami menggunakan //sebagai pemisah (yang tidak dapat terjadi sebaliknya dalam output finduntuk %p) dan mengonversi karakter baris baru ke karakter NUL (yang tidak dapat terjadi dalam perluasan %patau %l).

Stéphane Chazelas
sumber
1

Jika saya mengerti dengan benar, Anda ingin memeriksa bahwa symlink menunjuk ke tujuan teoritis yang sama, atau bahwa jika seseorang bukan symlink, file yang lain tertaut ke file yang sama. Ini harus melakukan apa yang Anda inginkan:

#!/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
Chris Down
sumber
@StephaneChazelas Itu kesalahan saya, saya bermaksud menggunakan -m, bukan -f. Terima kasih!
Chris Down
Sebenarnya, itu tidak akan berhasil jika satu-satunya perbedaan adalah jumlah karakter baris baru di target symlink.
Stéphane Chazelas
Saya juga tidak akan menggunakan -m.
Stéphane Chazelas
@StephaneChazelas Untuk alasan apa? Tanpa itu, symlink relatif yang benar-benar menunjuk ke file yang sama akan gagal perbandingan ini.
Chris Down
Jika /home/test/file1symlink adalah /etc/rc.d/whatever, atau keduanya symlink /, itu akan melaporkan bahwa mereka sama. Saya pikir OP ingin melihat perbedaan dalam "path" yang tersimpan di symlink, bukan apakah mereka menyelesaikan ke file yang sama (yang Anda miliki [[ a -ef b ]]).
Stéphane Chazelas