Яка різниця між 'rm' та 'unlink'?


55

Якщо припустити, що ви знаєте, що мета - це символьне посилання, а не файл, чи є різниця між використанням rmта unlinkвидаленням посилання?


3
Це досить добре висвітлено в ServerFault: serverfault.com/questions/38816/…
slm

@ slm ♦ Відповіді відповідають на це запитання, але це питання інше, він говорить: "Припустимо, що ви знаєте, що ціль є символічним посиланням, а не файлом".
Стефан Гурішон

Не схоже, що ви прийняли відповідь тут @ IQAndreas. Будь ласка, зробіть це, якщо вони допомогли вам.
Сірий

Відповіді:


56

Щоразу, коли у вас виникають такі питання, найкраще скласти невеликий тест, щоб побачити, що насправді відбувається. Для цього можна скористатися strace.

від’єднати

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

рм

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

Якщо ви подивитесь на два результуючі файли журналу, ви можете "побачити", що насправді робить кожен виклик.

Зламатися

З unlinkйого викликом unlink()системний виклик:

....
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)                           = ?
....

З rmце трохи іншим шляхом:

....
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 +++
...

Система викликає unlink()і unlinkat()по суті однакові, за винятком відмінностей, описаних на цій головній сторінці: http://linux.die.net/man/2/unlinkat .

витяг

Системний виклик unlinkat () працює точно так само, як або від’єднати (2), або rmdir (2) (залежно від того, чи містить прапор AT_REMOVEDIR прапор), за винятком відмінностей, описаних на цій сторінці керівництва.

Якщо ім'я шляху, вказане у назви шляху, є відносним, воно інтерпретується відносно до каталогу, на який посилається дескриптор файлу dirfd (а не відносно поточного робочого каталогу процесу виклику, як це робиться unlink (2) та rmdir (2 ) для відносної назви шляху).

Якщо ім'я шляху, вказане у назви шляху, є відносним, а dirfd - спеціальним значенням AT_FDCWD, то ім'я тракту інтерпретується відносно поточного робочого каталогу процесу виклику (наприклад, від’єднання (2) та rmdir (2)).

Якщо ім'я шляху, вказане у назви шляху, абсолютно, то dirfd ігнорується.


1
Оскільки це дає AT_FDCWD, різниці між unlinkта і фактично немає unlinkat.
Бармар

6
Мені приємно читати цю відповідь, тому що я просто "навчився ловити рибу" потужним, гнучким способом, коли часто я дістаю рибу або іноді "навчусь ловити рибу" базовим чином :-)
мудрець

21

POSIX вказує, що unlinkутиліта викликає функцію бібліотеки C unlinkі нічого іншого. Тут немає жодних варіантів. Якщо ви передасте дійсне ім'я шляху до чогось, що не є каталогом, і якщо у вас є дозволи на запис до каталогу, де живе цей об’єкт, unlinkвилучите його.

rm- це традиційна команда Unix, яка має трохи інших функціональних можливостей, і не зовсім суперсета unlink(див. нижче).

По-перше, rmпроводить перевірки безпеки. Якщо ви намагаєтеся rmоб'єкт, до якого у вас немає дозволів на запис (які не мають значення для вашої здатності його видаляти: безпосередньо дозволу є!), rmТим не менш, відмовляється, якщо -fне зазначено. rmзазвичай скаржиться, якщо файл не існує, як це робиться unlink; проте з -f, rmне скаржиться. Це часто використовується в Makefiles ( clean: @rm -f $(OBJS) ...), тому make cleanне виходить з ладу, коли нічого не можна видалити.

По-друге, rmє -iможливість інтерактивного підтвердження видалення.

В- третіх, rmє -rрекурсивно видалення каталогу, яка є те , що unlinkне потрібно робити, так як функція бібліотеки C не робить цього.

unlinkУтиліта точно не урізана rm. Він виконує підмножину того, що rmробить, але має семантику, яка є комбінацією rm з -f і rm без -f .

Припустимо, ви хочете просто видалити звичайний файл незалежно від його власних дозволів. Крім того, припустимо, що ви хочете, щоб команда вийшла з ладу, якщо файл не існує або будь-яка інша причина. Ні, rm fileні rm -f fileвідповідає вимогам. rm fileвідмовиться, якщо файл не піддається запису. Але rm -f fileбуде нехтувати скаргою, якщо файл відсутній. unlink fileвиконує роботу.

unlinkбув, мабуть, представлений тому rm, що занадто розумний: іноді потрібно просто чисту unlinkсемантику Unix : "будь-ласка, скасуйте цей запис у каталозі, якщо дозволи дозволу каталогу" .


2
Тут найясніша відповідь. Це фактично дає випадок використання для , unlinkа не тільки з описом відмінностей.
Wildcard

19

З одним файлом, rm та unlink виконайте те саме завдання, видаліть файл. Як визначено POSIX, rmі unlinkобидва вимагають відключення () системного виклику.

У GNU rmвін закликає unlinkat () системний виклик, що еквівалентно функції unlink()або rmdir (), за винятком випадків, коли шлях визначає відносний шлях.

Примітка

У деяких системах unlinkтакож можна видалити каталог. Принаймні, в системі GNU unlinkніколи не можна видалити ім'я каталогу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.