Якщо припустити, що ви знаєте, що мета - це символьне посилання, а не файл, чи є різниця між використанням rm
та unlink
видаленням посилання?
Якщо припустити, що ви знаєте, що мета - це символьне посилання, а не файл, чи є різниця між використанням rm
та unlink
видаленням посилання?
Відповіді:
Щоразу, коли у вас виникають такі питання, найкраще скласти невеликий тест, щоб побачити, що насправді відбувається. Для цього можна скористатися 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 ігнорується.
AT_FDCWD
, різниці між unlink
та і фактично немає unlinkat
.
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 : "будь-ласка, скасуйте цей запис у каталозі, якщо дозволи дозволу каталогу" .
unlink
а не тільки з описом відмінностей.
З одним файлом, rm та unlink виконайте те саме завдання, видаліть файл. Як визначено POSIX, rm
і unlink
обидва вимагають відключення () системного виклику.
У GNU rm
він закликає unlinkat () системний виклик, що еквівалентно функції unlink()
або rmdir (), за винятком випадків, коли шлях визначає відносний шлях.
Примітка
У деяких системах unlink
також можна видалити каталог. Принаймні, в системі GNU unlink
ніколи не можна видалити ім'я каталогу.