Простой способ удалить файл и все его ссылки (одновременно)

Я нашел много вопросов о том, как удалить символьные ссылки только или удалить символьные ссылки на основе их содержания, но никто не спросил, как сделать то, что я хочу сделать.

Возьмите следующий пример

file-l -> ../file
file-l2 -> ../file

Я хочу удалить file, file-l, и file-l2 одним махом, не зная местоположения других файлов, предпочтительно путем определения file как аргумент. (предположите, что я имею 100 + ссылки на тот же файл в случайных местах на всем протяжении файловой системы). Прежде всего, я предпочел бы сценарий оболочки или встроенную программу, но внешние программы также хорошо.

После unlink и rm не удалось обеспечить желаемую функциональность, у меня первоначально была идея использовать inodes или stat или что-то, но...

$ stat test
  File: ‘test’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 811h/2065d  Inode: 27001032    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/  braden)   Gid: ( 1000/  braden)
Access: 2015-08-30 21:30:35.578786598 -0600
Modify: 2015-08-30 21:30:35.578786598 -0600
Change: 2015-08-30 21:30:35.578786598 -0600
 Birth: -
$ stat test-l
  File: ‘test-l’ -> ‘test’
  Size: 4           Blocks: 0          IO Block: 4096   symbolic link
Device: 811h/2065d  Inode: 27001033    Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/  braden)   Gid: ( 1000/  braden)
Access: 2015-08-30 21:30:42.074786598 -0600
Modify: 2015-08-30 21:30:41.426786598 -0600
Change: 2015-08-30 21:30:41.426786598 -0600
 Birth: -

Мало того, что символьная ссылка имеет уникальный inode (это - данный), но, кажется, нет никакой информации кроме имени файла, которое я мог использовать, чтобы прийти к заключению, что "да, это - символьная ссылка на файл, который я хочу". Если я использую имя файла, тем не менее, затем, я должен иметь дело с regex-адом. Это - что-то, чего я лично хотел бы избежать с тех пор, на практике, имена файлов содержат символы как пространство, метасимволы (?![]{}.,), и символы unicode.

Я также хотел бы избежать вещей как awk, жемчуга, сумасшедшие взломы, которые используют ошибки/недостатки дизайна в ударе 4.2. XX, и другой странный материал, который, вероятно, не работал бы правильно (если вообще) на новой установке, например, Дуга Linux или CentOS. Я должен в основном смочь работать, сказал, что команда/сценарий out-of-the-box в системе, которая испытывает недостаток в awk, sed, жемчуге, рубине и Python, и выполняет удар 4.1 как его оболочка.

Если бы это не возможно, то я, по крайней мере, предпочел бы, чтобы сценарий/команда использовал / повсеместный, как vi, cat, ls, и т.д.

Абсолютный минимум моих требований то, что решение:

  • может удалить файл и все его символьные ссылки только с исходным файлом как аргумент
  • может сделать так, не зная имена или местоположения упомянутых символьных ссылок
  • может сделать так на символьных ссылках переменных имен и переменных местоположений
  • работы в новой, минимальной установке Дуги Linux (или подобная минимальная система)
  • не гольф кода
  • regexes, разумный и легкий для понимания

Это - то, как я пытаюсь разработать свои собственные сценарии, таким образом, я считаю это разумным. Но я, тем не менее, надеюсь, что это не слишком требовательно.

Спасибо.


Править: Я чувствую, что обязан показать свою работу. Просто запрос сценария заставляет меня чувствовать себя подобно толчку. Так, это - то, что я имею:

get_lnk(){
    gl_file="$1"
    gl_orig_a=( $(ls -l "$gl_file") )
    gl_orig="${gl_orig_a[-1]}"
}
for i in *; do 
    get_lnk "$i"
    echo "file: $gl_file"
    echo "links to: $gl_orig"
    echo
done

# output:

file: file-l
links to: ../file

file: file-l2
links to: ../file

Это печатает название символьной ссылки и название файла, на который это указывает. Это - на самом деле противоположность того, что я пытаюсь сделать, но довольно полезен (когда все ссылки находятся в том же месте).

2
задан 31 August 2015 в 07:39

1 ответ

Скажем, у Вас есть файл, названный file1 в ~/tmp, и скажем, что Вы хотите рекурсивно удалить все символьные ссылки на file1 в ~/tmp;

Используя find:

find ~/tmp -lname ~/tmp/file1 -exec rm {} +
  • ~/tmp: указывает путь к иерархии каталогов, в которой можно искать;
  • -lname: поиски только символьных ссылок, связывающихся с ~/tmp/file1;
  • -exec rm {} +: удаляет все результаты;

Демонстрационный вывод на тестовой иерархии каталогов:

user@debian ~/tmp % tree
.
├── 1
│   ├── 2
│   │   ├── 3
│   │   │   ├── link3-1 -> /home/user/tmp/file1
│   │   │   └── link3-2 -> /home/user/tmp/file2
│   │   ├── link2-1 -> /home/user/tmp/file1
│   │   └── link2-2 -> /home/user/tmp/file2
│   ├── link1-1 -> /home/user/tmp/file1
│   └── link1-2 -> /home/user/tmp/file2
├── file1
└── file2

3 directories, 8 files
user@debian ~/tmp % find . -lname ~/tmp/file1 -exec rm {} +
user@debian ~/tmp % tree
.
├── 1
│   ├── 2
│   │   ├── 3
│   │   │   └── link3-2 -> /home/user/tmp/file2
│   │   └── link2-2 -> /home/user/tmp/file2
│   └── link1-2 -> /home/user/tmp/file2
├── file1
└── file2

3 directories, 5 files
2
ответ дан 2 December 2019 в 03:52

Другие вопросы по тегам:

Похожие вопросы: