Nóng để làm khác biệt kiểm tra một liên kết symlink chính nó?


8

Trong Linux, người ta có thể sử dụng lệnh diffđể kiểm tra sự khác biệt của các tệp. Tôi sử dụng nó để kiểm tra sự khác biệt giữa hai mô-đun, cả hai được sao chép vào /tmp.

Tuy nhiên, cả hai mô-đun đều có liên kết tượng trưng, ​​có thể không được trỏ đến tệp chính xác, vì các mô-đun đã được sao chép vào /tmpthư mục. Nhưng điều này không quan trọng. Những gì tôi muốn kiểm tra là nếu các liên kết tượng trưng giống nhau.

Ví dụ, trong một mô-đun, symlink đọc

/home/test/file1

và trong trường hợp khác, symlink đọc:

/etc/rc.d/whatever

diffbây giờ ném một lỗi vì - nói chung - nó không thể tìm thấy tệp. Nhưng tôi muốn diffnói: "Này, những liên kết tượng trưng đó không giống nhau" bất kể các liên kết có trỏ đến các tệp hợp lệ hay không.

Câu hỏi: Làm thế nào có thể difflàm điều đó, tức là không cố gắng theo các liên kết, nhưng để khác biệt các liên kết?

Câu trả lời:


6

Hãy thử GNU diffphiên bản 3.3 trở lên với --no-dereferencetùy chọn (và có lẽ là tùy chọn --recursive):

diff --recursive --no-dereference tree1root tree2root

Bạn có thể thịt này ra một chút? Có lẽ đưa ra một ví dụ về làm thế nào nó có thể được sử dụng? Điều này có ý nghĩa của một câu trả lời hoàn toàn tốt nhưng chúng tôi muốn câu trả lời của chúng tôi rõ ràng hơn và dài dòng hơn ở đây.
terdon

3

Kể từ phiên bản 3.3, GNU diff không hỗ trợ các liên kết tượng trưng, ​​nhưng sau đó so sánh các đường dẫn mà chúng trỏ tới.

Cài đặt GNU diffutils> = 3.3 và sử dụng tùy chọn '--no-dereference'; không có lựa chọn ngắn cho điều đó.

Chẩn đoán sẽ im lặng nếu các đường dẫn bằng nhau, hoặc:

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

nếu các đường dẫn khác nhau.


1

Với các công cụ GNU:

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

Nói một cách chính xác, điều đó không thể phân biệt giữa một liên kết tượng trưng được gọi là ađiểm b -> cvà điểm được gọi là a -> bđiểm đó c, chưa kể đến các vấn đề với tên tệp chứa ký tự dòng mới, nhưng điều đó tạo ra đầu ra dễ đọc hơn mạnh mẽ hơn:

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)

Ở đó, chúng tôi sử dụng //như dấu phân cách (không thể xảy ra theo cách khác trong đầu ra của findfor %p) và chuyển đổi các ký tự dòng mới thành các ký tự NUL (không thể xảy ra khi mở rộng %pcũng không %l).


1

Nếu tôi hiểu chính xác, bạn muốn kiểm tra xem các liên kết tượng trưng đến cùng đích lý thuyết hay nếu một không phải là một liên kết tượng trưng, ​​thì tệp khác liên kết đến cùng một tệp. Điều này sẽ làm những gì bạn muốn:

#!/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 Đó là lỗi của tôi, tôi có nghĩa là để sử dụng -m, không phải -f. Cảm ơn!
Chris Xuống

Nói đúng ra, điều đó sẽ không hiệu quả nếu sự khác biệt duy nhất là số lượng ký tự dòng mới trong các mục tiêu của các liên kết tượng trưng.
Stéphane Chazelas

Tôi cũng sẽ không sử dụng -m.
Stéphane Chazelas

@StephaneChazelas Vì lý do gì? Không có nó, các liên kết tương đối thực sự trỏ đến cùng một tệp sẽ thất bại so sánh này.
Chris Xuống

Nếu /home/test/file1là một liên kết tượng trưng /etc/rc.d/whateverhoặc cả hai đều là một liên kết tượng trưng /, nó sẽ báo cáo chúng giống nhau. Tôi nghĩ rằng OP muốn thấy sự khác biệt trong "đường dẫn" được lưu trữ trong liên kết tượng trưng, ​​chứ không phải là liệu họ có giải quyết cùng một tệp hay không (mà bạn có [[ a -ef b ]]).
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.