Tôi biết các liên kết cứng là gì, nhưng tại sao tôi sẽ sử dụng chúng? Các tiện ích của một liên kết cứng là gì?
Tôi biết các liên kết cứng là gì, nhưng tại sao tôi sẽ sử dụng chúng? Các tiện ích của một liên kết cứng là gì?
Câu trả lời:
Ưu điểm chính của liên kết cứng là, so với liên kết mềm, không có hình phạt về kích thước hoặc tốc độ. Liên kết mềm là một lớp bổ sung trên đầu truy cập tệp thông thường; hạt nhân phải hủy đăng ký liên kết khi bạn mở tệp và việc này sẽ mất một ít thời gian. Liên kết cũng chiếm một lượng nhỏ dung lượng trên đĩa, để giữ văn bản của liên kết. Những hình phạt này không tồn tại với các liên kết cứng vì chúng được tích hợp vào chính cấu trúc của hệ thống tập tin.
Cách tốt nhất mà tôi biết để thấy điều này là:
$ ls -id .
1069765 ./
$ mkdir tmp ; cd tmp
$ ls -id ..
1069765 ../
Các -i
tùy chọn để ls
làm cho nó cung cấp cho bạn số inode của tập tin. Trên hệ thống mà tôi đã chuẩn bị ví dụ trên, tôi tình cờ ở trong một thư mục có số inode 1069765, nhưng giá trị cụ thể không thành vấn đề. Nó chỉ là một giá trị duy nhất xác định một tệp / thư mục cụ thể.
Điều này nói là khi chúng ta đi vào thư mục con và xem xét một mục hệ thống tập tin khác được gọi ..
, nó có cùng số inode mà chúng ta đã nhận được trước đó. Điều này không xảy ra vì shell đang diễn giải ..
cho bạn, như xảy ra với MS-DOS và Windows. Trên hệ thống tập tin Unix ..
là một mục thư mục thực sự; nó là một liên kết cứng trỏ trở lại thư mục trước đó.
Liên kết cứng là các đường gân liên kết các thư mục của hệ thống tập tin lại với nhau. Ngày xửa ngày xưa, Unix không có liên kết cứng. Chúng được thêm vào để biến hệ thống tệp phẳng ban đầu của Unix thành một hệ thống tệp phân cấp.
(Để biết thêm về điều này, hãy xem Tại sao '/' có mục '..'? )
Nó cũng hơi phổ biến trên các hệ thống Unix đối với một số lệnh khác nhau được thực thi bởi cùng một tệp thực thi. Nó dường như không còn là vấn đề trên Linux nữa, nhưng trên các hệ thống tôi đã sử dụng trước đây cp
, mv
và rm
tất cả đều giống nhau. Sẽ có ý nghĩa nếu bạn nghĩ về nó: khi bạn di chuyển một tệp giữa các tập, nó thực sự là một bản sao theo sau là loại bỏ, do đó mv
đã phải thực hiện các chức năng của hai lệnh khác. Việc thực thi có thể tìm ra thao tác nào sẽ cung cấp bởi vì nó được thông qua tên mà nó được gọi bởi.
Một ví dụ khác, phổ biến trong các Linux nhúng, là BusyBox , một tệp thực thi duy nhất thực hiện hàng tá lệnh.
Tôi nên chỉ ra rằng trên hầu hết các hệ thống tập tin, người dùng không được phép tạo liên kết cứng đến thư mục. Các mục .
và ..
được tự động quản lý bởi mã hệ thống tập tin, thường là một phần của kernel. Hạn chế tồn tại bởi vì có thể gây ra sự cố nghiêm trọng về hệ thống tệp nếu bạn không cẩn thận với cách bạn tạo và sử dụng các liên kết cứng của thư mục. Đây là một trong nhiều lý do liên kết mềm tồn tại; họ không mang cùng rủi ro.
Một cách sử dụng các liên kết cứng cực kỳ hữu ích là trong các bản sao lưu gia tăng kết hợp với rsync. Nó tiết kiệm rất nhiều không gian và làm cho thủ tục phục hồi thực sự dễ dàng. Tôi sử dụng phương pháp đó để sao lưu trong các máy chủ của tôi.
Hãy dành chút thời gian để đọc lời giải thích này .
Nếu sau khi đọc trang wikipedia đó, câu hỏi của bạn là "tại sao tôi lại sử dụng chúng" thì bạn không hiểu liên kết cứng là gì.
Một liên kết là một mục thư mục trỏ đến các khối trên đĩa. Nói cách khác, mọi tệp trên hệ thống của bạn đều có ít nhất một liên kết. Khi bạn rm
một tập tin cuộc gọi hệ thống thực tế là unlink()
. Nó loại bỏ các mục thư mục. Các khối trên đĩa không thay đổi nhưng liên kết đã biến mất, do đó tệp sẽ bị xóa khỏi danh sách thư mục.
Cá nhân bạn có thể không bao giờ sử dụng các liên kết cứng, nhưng tất cả chúng đều trên hệ thống của bạn. Ví dụ:
$ ls -li /bin | grep 53119771
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bunzip2
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bzcat
53119771 -rwxr-xr-x 3 root root 26292 2010-08-18 10:15 bzip2
Bạn có thể thấy điều đó bunzip2
, bzcat
và bzip
tất cả đều sử dụng cùng một nút. Về bản chất, nó là một tệp có ba tên. Bạn có thể có ba bản sao của tập tin, nhưng tại sao? Nó sẽ chỉ sử dụng hết dung lượng đĩa không cần thiết.
/bin
, tôi đoán đó là một trong những nguồn gây nhầm lẫn. Tại sao đôi khi thực thi sẽ được liên kết và đôi khi - liên kết cứng?
Có bất kỳ số lượng sử dụng. Tôi sử dụng chúng để tạo các khóa dựa trên tập tin. Cuộc gọi hệ thống liên kết (2) là nguyên tử, không giống như hầu hết các cuộc gọi hệ thống khác.
Một cách sử dụng khác là trong rsnapshot, trong đó các bản sao lưu được thực hiện theo thời gian bằng cách sử dụng các liên kết cứng để giảm dung lượng đĩa. Nếu một tệp không thay đổi, thì tệp đó được liên kết cứng với các phiên bản cũ hơn của tệp, các tệp đã thay đổi sẽ được sao chép lại.
Tôi cũng sử dụng chúng để trao đổi các tệp cấu hình trên các máy chủ: rm file.cfg && ln ~/tmp/file.cfg file.cfg
sau đó các tệp ~ / tmp / * có thể bị xóa một cách an toàn.
ln
và rm
thay vì chỉ một mv
?
Để thêm vào một số cuộc thảo luận tốt đã có mặt ...
(inode, name)
cặp định dạng cố định có nghĩa là không có thêm chi phí trong hệ thống tập tin để có các liên kết cứng (miễn là chúng tôi ngăn chặn chu kỳ bằng cách không cho phép hardlinke vào các thư mục (trừ .
và ..
(điều này có bắt đầu giống như bất kỳ ai khác không?)))vì vậy chúng tôi nhận được chúng miễn phí.
Tôi có lẽ nên bao gồm một kịch bản cạm bẫy của các liên kết cứng. Một liên kết cứng sẽ chỉ là cùng một tệp có tên khác và / hoặc một vị trí khác miễn là tệp được liên kết ban đầu tồn tại . Thậm chí không đúng khi nghĩ tệp là "bản gốc": cả hai đều là mục nhập thư mục theo quyền riêng của chúng và cả hai (hoặc nhiều hơn) đều là các đồng đẳng ngang nhau. Đối với các tệp tồn tại lâu, đây có thể là một phước lành, nhưng nếu một trong các cặp bị xóa và sau đó được tạo, ngay cả với cùng tên và nội dung, các tệp sẽ tách ra.
Giả sử bạn đã tạo một /foo/myfile
liên kết cứng liên kết đến /repo/myfile
. Cả hai đều là con trỏ đến cùng một dữ liệu tệp; thay đổi một, thay đổi khác. Nhưng giả sử điều đó /repo
xảy ra để giữ một kho lưu trữ Git. Nếu bạn kiểm tra một nhánh không chứa myfile
trong đó, /repo/myfile
sẽ bị xóa. Tại thời điểm này, /foo/myfile
trở thành một bản sao đơn giản /repo/myfile
, vì đó là lúc mà cặp kia không được liên kết. Thậm chí thật dễ dàng để không nhận thấy khi bạn lật giữa các nhánh mà tệp tiết mục thay đổi, nhưng, khi bạn kiểm tra nhánh ban đầu, một tệp mới/repo/myfile
được tạo bởi Git. Nếu bạn không chú ý, bạn sẽ tự hỏi tại sao hai tệp bây giờ có nội dung khác nhau, mặc dù điều này rất dễ hiểu, vì mối quan hệ liên kết cứng giữa các tệp không biết về tên của chúng. Ngược lại, một liên kết mềm sẽ tồn tại qua chu trình xóa-tạo này.
Mặt khác, phần mềm sử dụng các liên kết cứng nhận thức sâu sắc về điều này và Git là một ví dụ điển hình. Git nhân bản một kho lưu trữ trên cùng một hệ thống tệp gần như miễn phí, vì nó sử dụng các liên kết cứng theo mặc định thay vì sao chép các tệp. Đối với Git, liên kết cứng là trường hợp sử dụng hoàn hảo, vì các tệp đối tượng và gói của nó không bao giờ thay đổi, do đó, một bản sao của kho lưu trữ sẽ không bao giờ sửa đổi cái khác (Git biết không phải các tệp có thể sửa đổi liên kết cứng) và bất kỳ bản sao nào cũng có thể đã xóa mà không có bất kỳ biện pháp phòng ngừa nào: không cần phải theo dõi cái nào là "bản gốc" và thực sự chứa các tệp: bất kỳ liên kết cứng nào cũng là một đối tác bình đẳng và "chứa" toàn bộ tệp. Liên kết mềm sẽ không hoạt động ở đây.
Một ưu điểm khác của liên kết cứng là bất kỳ liên kết nào cũng có thể được di chuyển mà không phá vỡ quyền truy cập vào nội dung tệp. Với các liên kết mềm, di chuyển tệp gốc sẽ hiển thị tất cả các liên kết mềm đến nó.
Điểm mấu chốt là trong nhiều trường hợp sử dụng, loại liên kết hoạt động tốt như nhau, nhưng trong một số hoặc loại khác là lợi thế. Hiệu quả, được đề cập trong nhiều câu trả lời ở đây, có lẽ là một mối quan tâm rất nhỏ với các máy và hệ thống tập tin hiện đại, trừ khi bạn đang quét hệ thống tập tin trên chip FLASH của bộ điều khiển nhúng. Sự khác biệt về chức năng là quan trọng hơn, và thường chỉ ra các hạn chế kỹ thuật và lựa chọn cuối cùng:
Ngoài ra, tôi phải chỉ ra rằng cuộc gọi thư viện xóa một tệp được gọi unlink()
vì một lý do! Mỗi mục nhập thư mục chỉ là một liên kết cứng ban đầu với nút inode của nó.