Trường hợp sử dụng cho liên kết cứng? [đóng cửa]


40

Trong những tình huống nào người ta sẽ muốn sử dụng một liên kết cứng hơn là một liên kết mềm? Cá nhân tôi chưa bao giờ gặp phải tình huống tôi muốn sử dụng liên kết cứng qua liên kết mềm và trường hợp sử dụng duy nhất tôi gặp phải khi tìm kiếm trên web là sao chép các tệp giống hệt nhau .


4
Có những câu trả lời tốt dưới đây, nhưng hãy xem xét bối cảnh lịch sử (moot). Khi Unix còn mới, các ổ đĩa chậm và có dung lượng và bộ đệm hạn chế. Một liên kết cứng chỉ đơn giản là một mục nhập trực tiếp khác trong hệ thống tệp vào cùng một tệp. Cho dù bạn đang truy cập ls , hoặc như bạn muốn gọi nó, danh sách , đều không liên quan. Nếu bạn đã tạo danh sách một liên kết mềm, việc sử dụng nó sẽ liên quan đến việc tìm kiếm nó trong thư mục, đọc tệp đặc biệt được gọi là danh sách , xem rằng bạn muốn tệp ls , tìm ls trong thư mục và đọc tệp ls thực tế từ đĩa. Một sự khác biệt rất lớn trong hiệu suất!
RichF

16
Vâng, liên kết cứng đầu tiên đến một tập tin khá hữu ích.
Ngừng làm hại Monica

@OrangeDog: Có, nhưng bạn chỉ cần một trường đếm liên kết trong nút nếu bạn muốn hỗ trợ nhiều liên kết. (Bạn có thể cần một lá cờ cho các phiên bản trong bộ nhớ của inode để xử lý các trường hợp không liên kết nhưng vẫn mở fsck sau một vụ tai nạn mà không ghi nhật ký vẫn sẽ phải tìm kiếm inodes không có liên kết một trong hai cách..)
Peter Cordes

1
Ngữ nghĩa thư mục POSIX sẽ phải được thiết kế khác nhau: ..luôn luôn giống như .trong thư mục mẹ. Những thứ như findcó thể kiểm tra link-Count = 2 để phát hiện các thư mục lá và tránh statnhập các mục từ readdir để tìm thư mục con. Nhưng đó chỉ là một tính năng nhỏ được hỗ trợ bởi hỗ trợ cho các liên kết cứng của các tệp không phải thư mục (thông thường, symlink, thiết bị, ổ cắm và ống có tên). (Có, các liên kết tượng trưng có inode riêng và có thể được liên kết cứng.)
Peter Cordes

1
Một lý do cho việc sử dụng các liên kết cứng mà tôi chưa thấy trong bài đánh giá về SO, về bản chất "toàn cầu". Tưởng tượng một hệ thống tập tin trong đó các tệp thường nhỏ (chủ yếu là các bản ghi nhớ ngắn), nhưng để giữ mọi thứ có tổ chức, bạn có thể cần con trỏ đến cùng một tệp ở những nơi khác nhau. Với các liên kết tượng trưng, ​​mỗi con trỏ sử dụng một nút. Các hệ thống tập tin như vậy có thể đã có vấn đề với việc hết inodes. Sử dụng các liên kết cứng như con trỏ giúp với vấn đề này. inodes bị giới hạn về số lượng; tên cho chúng không phải (ít nhất, không theo cùng một cách).
mathguy

Câu trả lời:


27

Ngoài việc sử dụng sao lưu được đề cập trong một nhận xét khác, mà tôi tin rằng cũng bao gồm các ảnh chụp nhanh trên ổ BTRFS, trường hợp sử dụng cho các liên kết cứng trên các liên kết mềm là một tập hợp các tệp được sắp xếp theo thẻ. (Không nhất thiết là phương pháp tốt nhất để tạo một bộ sưu tập, một phương pháp dựa trên cơ sở dữ liệu có khả năng tốt hơn, nhưng đối với một bộ sưu tập đơn giản có độ ổn định hợp lý, nó không quá tệ.)

Một bộ sưu tập phương tiện trong đó tất cả các tệp được lưu trữ trong một, phẳng, thư mục và được sắp xếp vào các thư mục khác dựa trên các tiêu chí khác nhau, ví dụ: năm, chủ đề, nghệ sĩ, thể loại, v.v. Đây có thể là bộ sưu tập phim cá nhân hoặc tập thể của một studio thương mại công trinh. Về cơ bản kết thúc, tập tin được lưu, không có khả năng được sửa đổi và sắp xếp, có thể vào nhiều vị trí theo liên kết.

Hãy nhớ rằng khái niệm "bản gốc" và "bản sao" không thể áp dụng cho các liên kết cứng: mọi liên kết đến tệp bản gốc, không có "bản sao" theo nghĩa thông thường. Tuy nhiên, đối với mô tả trường hợp sử dụng, các thuật ngữ bắt chước logic của hành vi.

"Bản gốc" được lưu trong thư mục "danh mục" và các "bản sao" được sắp xếp được liên kết cứng với các tệp đó. Các thuộc tính tệp trên các thư mục sắp xếp có thể được đặt thành r / o, ngăn chặn mọi thay đổi ngẫu nhiên đối với tên tệp và cấu trúc được sắp xếp, trong khi các thuộc tính trên thư mục danh mục có thể được sửa đổi khi cần. (Trường hợp đó sẽ là các tệp nhạc trong đó một số người chơi cố gắng đổi tên và sắp xếp lại các tệp dựa trên các thẻ được nhúng trong tệp phương tiện, từ đầu vào của người dùng hoặc truy xuất internet.) Ngoài ra, vì các thuộc tính của thư mục "sao chép" có thể khác với thư mục "gốc", cấu trúc được sắp xếp có thể được cung cấp cho nhóm hoặc thế giới, với quyền truy cập hạn chế trong khi "danh mục" chính chỉ có thể truy cập được đối với người dùng chính, với quyền truy cập đầy đủ. Tuy nhiên, các tệp sẽ luôn có cùng thuộc tính trên tất cả các liên kết đến nút đó. (ACL có thể được khám phá để nâng cao điều đó, nhưng không phải là lĩnh vực kiến ​​thức của tôi.)

Nếu bản gốc được đổi tên hoặc di chuyển (ví dụ: thư mục "danh mục" quá lớn để quản lý), các liên kết cứng vẫn còn hiệu lực, các liên kết mềm bị hỏng. Nếu "bản sao" được di chuyển và các liên kết mềm là tương đối, thì các liên kết mềm sẽ lại bị phá vỡ và các liên kết cứng sẽ không bị phá vỡ.

Lưu ý: dường như có sự không nhất quán về cách các công cụ khác nhau báo cáo việc sử dụng đĩa khi liên kết mềm. Với các liên kết cứng, tuy nhiên, nó có vẻ phù hợp. Vì vậy, với 100 tệp trong danh mục được sắp xếp thành một bộ "thẻ", có thể dễ dàng có 500 "bản sao" được liên kết. . Thật thú vị, nó báo cáo rằng cùng một cách sử dụng không gian đĩa, do đó, nó trông giống như một tập hợp lớn các tệp nhỏ cho các liên kết mềm và một tập hợp nhỏ các tệp lớn cho các liên kết cứng.

Một lưu ý cho loại trường hợp sử dụng này là trong các hệ thống tệp sử dụng COW, sửa đổi "bản gốc" có thể phá vỡ các liên kết cứng, nhưng không phá vỡ các liên kết mềm. Nhưng, nếu mục đích là có bản sao chính, sau khi chỉnh sửa, lưu và sắp xếp, COW sẽ không nhập vào kịch bản.


3
FYI: ảnh chụp nhanh btrfs không phải là liên kết cứng. Họ có hành vi khác nhau (ví dụ: sửa đổi một bản sao không sửa đổi bản sao khác). Và statsẽ chỉ hiển thị một liên kết.
derobert

@derobert Không chắc ảnh chụp nhanh hoạt động như thế nào, điều tra nhỏ cho thấy những điều thú vị. Đối với các tệp / thư mục không thay đổi stathiển thị cùng số inode, nhưng ID thiết bị khác nhau. Phải có một cái gì đó để làm với cách subvolume được phủ lên trên khối lượng chính, hiếm khi được gắn kết. Tôi nghi ngờ rằng nếu âm lượng chính được gắn statsẽ hiển thị số lượng liên kết bằng với số ảnh chụp nhanh giữ phiên bản của tệp đó. COW có thể quan tâm đến việc sửa đổi không ảnh hưởng đến bất kỳ người nào khác. Chỉ là suy đoán dựa trên sự tò mò nhẹ, nhưng không đủ tò mò để đào sâu hơn.
Spellweaver Gypsy

Mỗi symlink có inode riêng, vì vậy nó sử dụng một mục inode trong hệ thống tập tin. Các hệ thống tệp Unix truyền thống yêu cầu bạn chọn bao nhiêu dung lượng dự trữ cho các nút trong thời gian tạo FS, thay vì phân bổ nó khi cần như XFS. Vì vậy, điều thực sự quan trọng là phiên bản symlink sẽ sử dụng nhiều nút hơn (thậm chí bên cạnh hàm ý dấu chân bộ đệm VFS).
Peter Cordes

23

Liên kết cứng rất hữu ích cho các trường hợp bạn không muốn ràng buộc sự tồn tại của cả hai tệp. Xem xét điều này:

touch a
ln -s a b
rm a

Bây giờ blà vô dụng. (Và các bước này có thể xảy ra cách nhau khá xa, được thực hiện bởi những người khác nhau, v.v.)

Trong khi đó với một liên kết cứng,

touch a
ln a b
rm a

b vẫn còn hiện diện và chính xác.


8
@MatthewCline Bạn sẽ muốn hành vi này khi quản lý sao lưu gia tăng hiệu quả. Đặc biệt là khi các bản sao lưu cũ bị xóa, trong một hệ thống sao lưu dựa trên liên kết mềm, bạn sẽ phải kiểm tra và gửi lại tất cả các tệp / liên kết sao lưu mới hơn vào một cơ sở hợp lệ, trong khi các liên kết cứng thực hiện công việc đó "miễn phí" ở mức độ inode. timeshift / backintime ví dụ sử dụng rộng rãi các liên kết cứng.
or Dixow

3
@or Dixow Tôi không nghĩ bạn muốn hành vi liên kết cứng ở bất cứ đâu gần hệ thống sao lưu của bạn. github.com/bit-team/backintime/wiki/ trên backintime dại dột cho rằng tất cả các thay đổi đối với các tệp sẽ theo chu trình loại bỏ thay vì cập nhật tại chỗ.
DepressionDaniel

10
@DepressionDaniel liên kết cứng là tốt trong một hệ thống sao lưu, bạn chỉ không muốn các bản sao lưu được liên kết cứng với các tập tin trực tiếp. Nhưng trong mọi trường hợp, không thể truy cập bản sao lưu trực tiếp từ hệ thống trực tiếp ...
Stephen Kitt

1
Đây không phải là một câu trả lời-- cụ thể, đây không phải là trường hợp sử dụng. Nó chỉ là một minh chứng cho hành vi liên kết cứng.
dùng394

1
@ ThomasPadron-McCarthy đó là một sự hiểu lầm. BiT chỉ sử dụng các liên kết cứng để liên kết các tệp giống hệt nhau trong các ảnh chụp nhanh khác nhau. Chúng KHÔNG được liên kết với tập tin gốc! (Tôi là Dev BiT)
Germar

11

Một chương trình có thể thay đổi hành vi của nó tùy thuộc vào tên được khởi chạy là:

$ ls -li `which pgrep` `which pkill`
208330 -r-xr-xr-x  2 root  bin  19144 Jul 26  2016 /usr/bin/pgrep
208330 -r-xr-xr-x  2 root  bin  19144 Jul 26  2016 /usr/bin/pkill

Mà trong nguồn được quyết định thông qua một cái gì đó như

if (strcmp(__progname, "pgrep") == 0) {
    action = grepact;
    pgrep = 1;
} else {
    action = killact;

mặc dù các chi tiết chính xác sẽ thay đổi tùy theo hệ điều hành và ngôn ngữ liên quan.

Điều này cho phép (hầu hết) mã giống hệt nhau không phải được biên dịch thành hai (hầu hết) các mã nhị phân giống hệt nhau. Hãy nhớ rằng unix ngày đến khi không gian đĩa là siêu đắt, mặc dù theo Stevens trong APUE chương 4, các liên kết được thực hiện trong BSD4.2 (1983) để thay thế các hạn chế khác nhau của liên kết cứng. Một chương trình thử nghiệm để kiểm tra xem tên symlink có được sử dụng làm tên chương trình có thể trông giống như không:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    printf("called as '%s'\n", *argv);
    exit(0);
}

Và thử nghiệm qua:

$ cc -o myname myname.c 
$ ln -s myname alias
$ ./myname
called as './myname'
$ ./alias
called as './alias'
$ 

4
Nhưng điều đó thường không được xử lý với các liên kết mềm?
Matthew Cline

1
@MatthewCline có thể là ngày hôm nay, nhưng các liên kết tượng trưng không tồn tại trước 4.2BSD (1983) theo Stevens trong APUE.
thrig

4
@thrig, câu hỏi đặc biệt yêu cầu các trường hợp sử dụng không thể được thực hiện bằng liên kết tượng trưng hoặc ít nhất là tốt hơn là sử dụng liên kết tượng trưng. Câu trả lời của bạn áp dụng cho cả HL và SL.
Marcelo

3
BusyBox đưa điều này đến mức tối đa.
Tối đa

8

Khi phần mềm P2P của tôi hoàn tất tải xuống một tệp nhất định, tệp sẽ được đặt trong một thư mục cụ thể. Các tập tin tải về hầu như không cần phải chỉnh sửa. Trường hợp phổ biến là tôi tạo một liên kết cứng trong một thư mục khác, nơi tôi cần tệp.

Ưu điểm:

  • Tôi vẫn chia sẻ tệp trong mạng P2P như tôi nên ngay cả khi tôi rmhoặc mv"bản sao".
  • Các tập tin cũng là ở nơi tôi cần nó; hầu hết các địa điểm như vậy không được chia sẻ.
  • Tôi có thể rm"bản gốc" để ngừng chia sẻ tệp; Thao tác này không ảnh hưởng đến "bản sao" ở vị trí mong muốn.
  • Không gian đĩa của tôi được sử dụng chỉ một lần.

Điểm chính: nếu tôi biết trước tập tin nào rmtrước tiên, tôi có thể đi với symlink. Nhưng tôi không bao giờ biết.


6

Hệ thống tập tin là một cách đơn giản và hiệu quả để tổ chức và phân loại các tập tin (đây là lý do chính để tồn tại). Liên kết cứng cho phép mức độ linh hoạt cao hơn trong vấn đề này.

Như đã đề cập, không có khái niệm về bản gốc và bản sao khi xử lý các liên kết cứng, tất cả các mục nhập thư mục (liên kết cứng) chỉ đơn giản là các tham chiếu đến sự tồn tại của tệp (trỏ đến nút của nó) không có quyền ưu tiên, do đó cũng không có liên kết cứng bị hỏng .. .

Vì vậy, ở đây có một số trường hợp sử dụng mà liên kết cứng tham dự nhưng liên kết mềm không :

  1. Hãy tưởng tượng bạn có một bộ sưu tập phim hoặc nhạc hoặc phương tiện khác và muốn áp dụng các tiêu chí phân loại khác nhau, như các bài hát được phân loại bởi nghệ sĩ trong một chi nhánh (mỗi nghệ sĩ có thư mục con riêng); theo thể loại trong một nhánh khác (mỗi thư mục con khác nhau), v.v. Tuy nhiên, bạn vẫn không muốn sao chép các tệp cũng như quyết định đặt "bản gốc" ở đâu để bạn có thể tự do phân loại lại mà không phải " quản lý "và liên kết lại các tập tin khi di chuyển để tránh các liên kết bị hỏng.

  2. Một lý do khác là để tránh lãng phí dung lượng lưu trữ cần thiết để có nhiều bản sao của cùng một tệp và cho phép tòa nhà chrootđược hưởng lợi từ một tập hợp con trong thư mục gốc của hệ thống tệp "chính" (liên kết tượng trưng không bao giờ có thể tham chiếu các tệp từ bên ngoài các chrootsandbox, ngay cả khi họ có đường dẫn tương đối).

  3. Một lý do rất quan trọng nhưng hiếm khi được đề cập để liên kết cứng tồn tại là các ..thư mục con. Các ..thư mục thực sự là (trong hầu hết các triển khai fix unix) đến thư mục mẹ, không có liên kết cứng, điều này phải được thực hiện theo một cách hoàn toàn khác, trong khi sự tồn tại của các liên kết cứng làm cho việc này rất dễ thực hiện.


1
Đối với điểm 1, sử dụng uuids làm tên 'chính tắc' cho các tệp và tạo tất cả các tên có thể đọc được của con người liên kết tượng trưng đến uuids, là một giải pháp thay thế.
R ..

Mặc dù gợi ý của uuids nghe có vẻ chính xác về mặt học thuật, sử dụng uuids cho tên tệp nghe có vẻ không thực tế lắm, và một lần nữa, mục tiêu là đơn giản hóa mọi thứ, không làm cho chúng trở nên khó hiểu hơn hoặc "ít người hiểu hơn". Bên cạnh đó, việc sử dụng tham chiếu tệp "chính tắc" sẽ chỉ là một sự bổ sung bổ sung cho inode tệp thực tế, vì vậy, không có lý do nào để thực hiện trong phương pháp này vì nó không có lợi thế, chỉ là nhược điểm như: tác động đến hiệu suất, bổ sung không gian đĩa để lưu trữ nhiều mục nhập thư mục hơn, có một loạt các tệp có tên "lạ" xung quanh ...
Marcelo

5

Rất phổ biến, ví dụ thực tế cần liên kết cứng:

git clone --reference <repository>

Bản sao này từ một repo Git cục bộ với sao chép gần như bằng không. Thay vì sao chép các tệp đối tượng (các tệp không thay đổi được Git sử dụng cho "cơ sở dữ liệu" của nó), nó chỉ đơn giản là liên kết cứng chúng.

Bất kỳ repo nào cũng có thể loại bỏ một đối tượng, nhưng inode vẫn hợp lệ cho phần còn lại của repos. Và nếu một đối tượng bị xóa khỏi tất cả các repos, nó sẽ bị xóa khỏi đĩa. Liên kết cứng làm cho một giải pháp đẹp mạnh mẽ và nhanh chóng. Rất phổ biến trong các máy chủ CI.


Có một phiên bản không liên kết cứng : git clone --shared <repository>. Điều này, tuy nhiên, hay thay đổi và có nhiều cảnh báo hơn vì mọi người đều làm việc trên cùng một thư mục.


4

Gần đây tôi đã có một trường hợp sử dụng cho một quy trình cập nhật có phần an toàn cho các hệ thống dựa trên U-Boot, trong đó uImagemột liên kết mềm chỉ vào hình ảnh để khởi động, ý tưởng là việc mất điện sẽ không gây ra vấn đề gì, bất kể ở điểm nào trong xử lý nó xảy ra (giả sử hệ thống tập tin chơi cùng):

ln image.bin backup_image.bin
ln -sf backup_image.bin uImage

// replace image.bin

ln -sf image.bin uImage
rm backup_image.bin

Không có liên kết cứng, nó sẽ không đơn giản.

/chỉnh sửa:

Nhờ các ý kiến ​​mà bây giờ tôi biết rằng sẽ tốt hơn để làm:

ln image.bin backup_image.bin
ln -sf backup_image.bin uImageNew
mv uImageNew uImage || rm -rf uImage && mv uImageNew uImage

// replace image.bin

ln -sf image.bin uImageNew
mv uImageNew uImage || rm -rf uImage && mv uImageNew uImage
rm backup_image.bin

(Đây rmlà ở đây để có thể thoát khỏi trạng thái lạ tốt hơn, ví dụ nếu uImagecó điều gì đó bất ngờ sẽ gây ra mvthất bại [nhưng không nhất thiết là ln -sfgiải pháp trước đó ].)


2
+1 vì về mặt khái niệm đây là một lý do rất hay, nhưng không may ln -sflà không phải là nguyên tử. Nó xóa symlink cũ và tạo một cái mới. Để khắc phục điều này, bạn cần tạo một liên kết tượng trưng mới với một tên tạm thời và rename(2)( mv) nó thành tên của cái bạn muốn thay thế.
R ..

@R .. Bạn nói đúng! 😲 stat("uImage", {st_mode=S_IFREG|0777, st_size=0, ...}) unlink("uImage"),symlink("backup_image.bin", "uImage")
phk

1
BTW, xem ở đây để biết phiên bản của install.shtôi giải quyết vấn đề: git.musl-libc.org/cgit/musl/tree/tools/install.sh
R ..

@R .. Lưu ý rằng mvngay cả với -fcó thể thất bại nếu đích đã tồn tại, ví dụ như một liên kết tượng trưng là một phần của vòng lặp liên kết tượng trưng. Bản demo:ln -sf foo bar; ln -sf bar foo; echo "Before:"; ls -l foo bar; >testfile; mv testfile foo || { echo "Using mv -f"; mv -f testfile foo; }; echo "After:"; ls -l foo bar
phk

3

Một cách sử dụng mà tôi đã có cho các liên kết cứng là khi tải xuống hoặc giải nén một tệp bị hỏng. Chương trình thực hiện tải xuống hoặc giải nén (chẳng hạn như giải nén hoặc unrar) thường sẽ tự động xóa tệp không đầy đủ khi gặp lỗi và thường không có tùy chọn để giữ nó. Nếu tôi muốn giữ tập tin, tôi có thể tạo một liên kết cứng với nó.


3

BackupPC là một hệ thống sao lưu sử dụng các liên kết cứng trên các máy chủ để cung cấp sự trùng lặp ở cấp độ tệp.

Các tệp được lưu trữ đầu tiên trong cây thư mục "pool" dựa trên hàm băm md5 của chúng. Bất kỳ bản sao lưu nào sử dụng tệp đó sẽ tạo liên kết cứng đến tệp nhóm. Khi sao lưu hết hạn / bị xóa, các liên kết cứng của chúng sẽ bị xóa khỏi hệ thống tập tin.

Liên kết cứng vượt trội hơn so với liên kết mềm ở đây vì chúng cung cấp tính năng tham chiếu tự động. Một công việc định kỳ sẽ xóa bất kỳ tệp nào trong thư mục nhóm không có nhiều liên kết.

Phương pháp này có một số nhược điểm (chủ yếu là khó sử dụng các công cụ dựa trên hệ thống tệp để sao chép cửa hàng sao lưu), nhưng thực tế nó đã được chứng minh là khá mạnh mẽ trong thực tế.


Một trường hợp sử dụng khác: máy chủ ứng dụng web tomcat java coi tên tệp là siêu dữ liệu. Một tập tin "chiến tranh" java phải được đặt tên dựa trên đường dẫn của nó trên máy chủ web.

ví dụ: foo.war là mã java phục vụ url/foo

Thật không may, nó giải quyết các liên kết tượng trưng trước khi đưa ra quyết định này.

Vì vậy, giả sử bạn muốn triển khai một bản dựng ứng dụng và đặt cho nó một tên tệp mô tả (ví dụ: với số hoặc ngày phát hành). Bạn không thể tạo một liên kết tượng trưng đến tệp bằng tên "thực" - bạn phải tạo một liên kết cứng.

foo.warsymlinked foo-20170129.warkhông hoạt động

foo.warliên kết cứng để foo-20170129.warlàm việc.

Tôi không thích hành vi tomcat này, nhưng các liên kết cứng cho tôi một cách xung quanh nó.

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.