Là hai tập tin liên kết cứng?


27

Làm thế nào tôi có thể biết nếu hai tập tin được liên kết cứng từ dòng lệnh? ví dụ: một cái gì đó liên kết này:

$ ls
fileA fileB fileC

$ is-hardlinked fileA fileB
yes

$ is-hardlinked fileA fileC
no

Câu trả lời:


37

Trên hầu hết các hệ thống tệp¹, một tệp được xác định duy nhất bởi số inode của nó , vì vậy tất cả những gì bạn cần kiểm tra là liệu hai tệp có cùng số inode và nằm trên cùng một hệ thống tệp không.

Ash, ksh, bash và zsh có cấu trúc kiểm tra cho bạn: toán tử đẳng thức tập tin -ef.

[ fileA -ef fileB ] && ! [ fileA -ef fileC ]

Đối với các trường hợp nâng cao hơn, hãy ls -i /path/to/fileliệt kê số inode của tệp. df -P /path/to/filehiển thị hệ thống tập tin nào tập tin được bật (nếu hai tập tin nằm trong cùng một thư mục, chúng nằm trên cùng một hệ thống tập tin). Nếu hệ thống của bạn có statlệnh, nó có thể hiển thị số inode và số hệ thống tập tin ( statthay đổi tùy theo hệ thống, kiểm tra tài liệu của bạn). Nếu bạn muốn xem nhanh các liên kết cứng trong một thư mục, hãy thử ls -i | sort(có thể chuyển sang awk ).

¹ Tất cả các hệ thống tập tin bản địa unix, và vài người khác như NTFS, nhưng trường hợp có thể không kỳ lạ như CramFS.


Và chắc chắn không phải trên bất cứ thứ gì dựa trên FAT, nơi nó sẽ được phát hiện dưới dạng tệp "được liên kết chéo".
Ignacio Vazquez-Abrams

4
Lưu ý rằng fileA -ef fileBcũng trả về 0(thành công) nếu fileAlà một liên kết tượng trưng fileBhoặc ngược lại hoặc cả hai đều liên kết đến cùng một tệp.
janmoesen

Làm thế nào để bạn thực sự chạy lệnh bạn đề nghị? Tôi đã thử [.bashrc -ef .bash / .bashrc] và các biến thể của điều này nhưng nó không thực sự hoạt động.
Charlie Parker

@CharlieParker [ .bashrc -ef .bash/.bashrc ]là chính xác. Dĩ nhiên, không có ngữ cảnh, tôi không biết tại sao nó lại không thực sự hoạt động. Bạn có thể so sánh các tệp sai, bạn không thể kiểm tra kết quả chính xác, bạn có thể sử dụng shell mà không -ef, ...
Gilles 'SO- đừng trở nên xấu xa'

2
@CharlieParker Lệnh này thực sự [và là một từ đồng nghĩa của test. Nhưng man [hoặc man testsẽ cung cấp cho bạn trang man của lệnh bên ngoài, trong khi mọi vỏ ngoài đều có lệnh tích hợp với các tùy chọn hơi khác nhau, vì vậy bạn cần tìm kiếm cái này trong hướng dẫn sử dụng của vỏ.
Gilles 'SO- ngừng trở nên xấu xa'

4
function is-hardlinked() {
    r=yes
    [ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
    echo $r
}

6
Lưu ý rằng điều này có thể là dương tính giả nếu hai tệp nằm trên các hệ thống tệp khác nhau nhưng tình cờ có cùng một nút. Bạn cũng cần kiểm tra số thiết bị ( stat -c %d). Và nếu bạn đang dùng Linux (được cung cấp statlệnh của bạn ), trình bao của bạn có [ fileA -ef fileB ]thể thực hiện trực tiếp tất cả điều này. Ngoài ra, lệnh của bạn ngắt một cách miễn phí với các tên tệp chứa khoảng trắng hoặc \[?*, hoặc bắt đầu bằng -: luôn đặt dấu ngoặc kép xung quanh lệnh susbtitutions ( "$(stat -c %i -- "$1")").
Gilles 'SO- ngừng trở nên xấu xa'

1
Tại sao bạn sử dụng một loạt các cấu trúc rườm rà nhưng di động, và sau đó functiontừ khóa không di động có tên hàm (trên tài khoản chứa dấu gạch ngang) vi phạm các quy ước POSIX trên các tên được phép?
Charles Duffy

Bạn quên trích dẫn của bạn $1$2. Bạn cũng có thể muốn sử dụng $()cú pháp thay vì backticks vì dấu ngoặc làm rõ nơi lệnh bắt đầu và nơi kết thúc và việc lồng nhau đơn giản hơn.
josch

3

Như poster đầu tiên đề xuất, bạn có thể viết một kịch bản dựa trên cái gì đó như thế này trên Linux:

stat -c '%i' fileA fileB fileC

4
Điều này là không đủ: bạn sẽ nhận được cùng một số cho hai tệp nếu ở trên các hệ thống tệp khác nhau nhưng tình cờ có cùng một nút. Bạn cũng cần kiểm tra số thiết bị ( stat -c %d). Và nếu bạn đang dùng Linux (được cung cấp statlệnh của bạn ), trình bao của bạn có [ fileA -ef fileB ]thể thực hiện trực tiếp tất cả điều này.
Gilles 'SO- ngừng trở nên xấu xa'

0

Với GNU find(1)phiên bản 4.2.11 trở lên, bạn cũng có thể sử dụng điều này:

if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
    echo yes
else
    echo no
fi

Nếu fileAcùng một tệp như fileBsau đó findsẽ in "có" và điều kiện trở thành đúng.

Ngược lại với việc sử dụng toán tử đẳng thức tập tin, điều -efnày sẽ tạo ra một quy trình mới.

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.