Sự khác biệt giữa 'rm' và 'unlink' là gì?


55

Giả sử bạn biết mục tiêu là một liên kết tượng trưng và không phải là một tệp, có sự khác biệt nào giữa việc sử dụng rmunlinkxóa liên kết không?


3
Điều này được trình bày khá tốt trên ServerFault: serverfault.com/questions/38816/ trên
slm

@ slm ♦ Các câu trả lời tương ứng với câu hỏi đó, nhưng câu hỏi này thì khác, nó nói: "Giả sử bạn biết mục tiêu là một liên kết tượng trưng chứ không phải là một tập tin".
Stéphane Gourichon

Không có vẻ như bạn đã chấp nhận câu trả lời ở đây @IQAndreas. Hãy làm như vậy nếu họ đã giúp bạn.
Xám

Câu trả lời:


56

Bất cứ khi nào bạn có những loại câu hỏi này, tốt nhất nên nghĩ ra một bài kiểm tra nhỏ để xem điều gì thực sự xảy ra. Đối với điều này, bạn có thể sử dụng strace.

bỏ liên kết

$ touch file1
$ strace -s 2000 -o unlink.log unlink file1

rm

$ touch file1
$ strace -s 2000 -o rm.log rm file1

Khi bạn xem 2 tệp nhật ký kết quả, bạn có thể "thấy" mỗi cuộc gọi đang thực sự làm gì.

Phá vỡ

Với unlinknó gọi unlink()cuộc gọi hệ thống:

....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3)                                = 0
unlink("file1")                         = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
....

Với rmmột con đường hơi khác:

....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid()                               = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK)      = 0
unlinkat(AT_FDCWD, "file1", 0)          = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
...

Hệ thống gọi unlink()unlinkat()về cơ bản là giống nhau ngoại trừ sự khác biệt được mô tả trong trang man này: http://linux.die.net/man/2/unlinkat .

đoạn trích

Cuộc gọi hệ thống unlinkat () hoạt động chính xác giống như hủy liên kết (2) hoặc rmdir (2) (tùy thuộc vào việc các cờ có bao gồm cờ AT_REMOVEDIR hay không) ngoại trừ các khác biệt được mô tả trong trang hướng dẫn này.

Nếu tên đường dẫn được đặt trong tên đường dẫn là tương đối, thì nó được hiểu tương đối với thư mục được gọi bởi bộ mô tả tệp dirfd (chứ không phải liên quan đến thư mục làm việc hiện tại của quá trình gọi, như được thực hiện bởi unlink (2) và rmdir (2 ) cho một tên đường dẫn tương đối).

Nếu tên đường dẫn được đặt trong tên đường dẫn là tương đối và dirfd là giá trị đặc biệt AT_FDCWD, thì tên đường dẫn được hiểu tương ứng với thư mục làm việc hiện tại của quá trình gọi (như unlink (2) và rmdir (2)).

Nếu tên đường dẫn được đặt trong tên đường dẫn là tuyệt đối, thì dirfd sẽ bị bỏ qua.


1
Vì nó cho AT_FDCWD, nên thực sự không có sự khác biệt giữa unlinkunlinkat.
Barmar

6
Tôi rất vui khi đọc câu trả lời này vì tôi chỉ "học cách câu cá" một cách mạnh mẽ, linh hoạt khi tôi thường xuyên bắt được một con cá hoặc đôi khi tôi "học cách câu cá" theo cách cơ bản trên SO :-)
hiền nhân

22

POSIX chỉ định rằng unlinktiện ích gọi unlinkhàm thư viện C và không có gì khác. Nó không có tùy chọn. Nếu bạn chuyển một tên đường dẫn hợp lệ cho một cái gì đó không phải là một thư mục và nếu bạn có quyền ghi vào thư mục nơi đối tượng đó sống, thì unlinksẽ xóa nó.

rmlà một lệnh Unix truyền thống có một chút chức năng khác và không hoàn toàn thay thế unlink(xem bên dưới).

Thứ nhất, rmthực hiện kiểm tra an toàn. Nếu bạn cố gắng để rmmột đối tượng mà bạn không có quyền ghi (không liên quan đến khả năng loại bỏ của bạn: thì quyền trực tiếp là!) rmTuy nhiên từ chối trừ khi -fđược chỉ định. rmthường phàn nàn nếu tập tin không tồn tại, như vậy unlink; tuy nhiên với -f, rmkhông phàn nàn. Điều này thường được khai thác trong Makefiles ( clean: @rm -f $(OBJS) ...) vì vậy make cleankhông thất bại khi không có gì để xóa.

Thứ hai, rm-itùy chọn để tương tác xác nhận xóa.

Thứ ba, rmđã -rxóa đệ quy một thư mục, đây là điều unlinkkhông bắt buộc phải làm, vì chức năng thư viện C không làm điều đó.

Các unlinktiện ích không chính xác là một tước bỏ rm. Nó thực hiện một tập hợp con của những gì rm, nhưng nó có ngữ nghĩa là sự kết hợp rm với -f và rm không có -f .

Giả sử bạn muốn xóa một tệp thông thường bất kể quyền của chính nó là gì. Hơn nữa, giả sử bạn muốn lệnh thất bại nếu tệp không tồn tại hoặc bất kỳ lý do nào khác. Không rm filephải cũng không rm -f fileđáp ứng yêu cầu. rm filesẽ từ chối nếu tập tin không thể ghi. Nhưng rm -f filesẽ bỏ qua khiếu nại nếu tập tin bị thiếu. unlink fileLàm công việc.

unlinkcó lẽ đã được giới thiệu vì rmquá thông minh: đôi khi bạn chỉ muốn unlinkngữ nghĩa thuần túy của Unix : "vui lòng làm cho mục nhập thư mục này biến mất nếu quyền của thư mục cho phép" .


2
Đây là câu trả lời rõ ràng nhất ở đây. Nó thực sự cung cấp cho các trường hợp sử dụng cho unlinkchứ không phải là sự khác biệt chỉ là mô tả.
tự đại diện

19

Với một tệp duy nhất, rmhủy liên kết thực hiện cùng một tác vụ, xóa tệp. Như POSIX đã xác định rmunlinkcả hai cuộc gọi đến cuộc gọi hệ thống hủy liên kết () .

Trong GNU rm, nó gọi tới lệnh gọi hệ thống unlinkat () , tương đương với hàm unlink()hoặc rmdir () trừ trường hợp đường dẫn chỉ định đường dẫn tương đối.

Ghi chú

Trên một số hệ thống, unlinkcũng có thể loại bỏ thư mục. Ít nhất là trong hệ thống GNU, unlinkkhông bao giờ có thể xóa tên của một thư mục.

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.