Intereting Posts
Как заставить Vim вести себя как «tail -f»? Как безопасно разрешить scp, но не ssh Установка FreeBSD с USB-Stick, но позже не может найти USB-Stick Может ли профиль терминала Gnome использовать UTF-8 по умолчанию? Как вызвать функцию bash из awk? Заменить шаблон, если перед вторым шаблоном – сохранить строку между двумя Невозможно подключить USB Wi-Fi к гостевому серверу Kali с помощью Virtual Box Встроенное устройство, раздел журнала, какая файловая система более устойчива и использует меньше операций чтения / записи? Как автоматически настроить громкость в соответствии со звуком вокруг меня? Разрешение Firefox не пропорционально Синхронизация Resilio не запускается при загрузке Замените awk и tr просто awk для преобразования в строчный регистр Запуск openvpn без привилегий root Почему я должен использовать «sudo», когда нахожусь в группе суперпользователей? Как установить беспроводной ключ с помощью nmcli интерактивно и безопасно, не вводя его в команду

В чем разница между «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 

Когда вы смотрите на 2 результирующих файла журнала, вы можете «видеть», что делает каждый вызов.

Сломать

С 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 () работает точно так же, как либо unlink (2), либо rmdir (2) (в зависимости от того, включают ли флаги флаг AT_REMOVEDIR), за исключением различий, описанных на этой странице руководства.

Если путь, указанный в пути, является относительным, то он интерпретируется относительно каталога, на который ссылается файловый дескриптор dirfd (а не относительно текущего рабочего каталога вызывающего процесса, как это делают unlink (2) и rmdir (2 ) для относительного пути).

Если имя пути, заданное в пути, является относительным, а dirfd является специальным значением AT_FDCWD, тогда имя пути интерпретируется относительно текущего рабочего каталога вызывающего процесса (например, unlink (2) и rmdir (2)).

Если имя пути, указанное в имени пути, является абсолютным, то dirfd игнорируется.

С одним файлом, rm и unlink выполняют ту же задачу, удалите файл. Как определено POSIX, rm и unlink оба вызова для системного вызова unlink () .

В GNU rm он вызывает системный вызов unlinkat () , что эквивалентно функции unlink() или rmdir (), за исключением случая, когда путь указывает относительный путь.

Заметка

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

POSIX указывает, что утилита unlink вызывает функцию unlink связи C-библиотеки и ничего больше. Это не имеет никакого значения. Если вы передадите действительное имя пути к тому, что не является каталогом, и если у вас есть права на запись в каталог, где живет этот объект, то unlink удалит его.

rm – это традиционная команда Unix, которая имеет немного другой функциональности и не является довольно большим набором unlink (см. ниже).

Во-первых, rm выполняет проверки безопасности. Если вы попытаетесь создать объект, к которому у вас нет прав на запись (которые не имеют отношения к вашей способности удалить его: прямые разрешения есть!) rm тем не менее отказывается, если не указано значение -f . rm обычно жалуется, если файл не существует, как и unlink ; однако с -f , rm не жалуется. Это часто используется в Makefile ( clean: @rm -f $(OBJS) ... ), поэтому make clean не clean: @rm -f $(OBJS) ... когда ничего не удалять.

Во-вторых, rm имеет параметр -i для интерактивного подтверждения удаления.

В-третьих, rm имеет -r для рекурсивного удаления каталога, от чего не требуется отменить связь, поскольку функция библиотеки C этого не делает.

Утилита unlink не является точно урезанной rm . Он выполняет подмножество того, что делает rm , но имеет семантику, которая представляет собой комбинацию rm с -f и rm без -f .

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

unlink вероятно, был введен потому, что rm слишком умный: иногда вам просто нужна чистая семантика unlink : «Пожалуйста, заставьте эту запись в каталоге уйти, если разрешить разрешения для каталога» .