it-swarm-ru.tech

Как я могу "связать" много сломанных символических ссылок?

У меня есть дерево каталогов, которое имеет кучу символических ссылок на файлы в /home... однако я переехал /home до /mnt/home и ​​нужен способ "связать" все символические ссылки. Существует ли такая функциональность или мне нужно написать скрипт для этого?

В качестве примера у меня есть что-то вроде следующего:

[[email protected] ~]# ls -l /mnt/home/someone/something
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/e

/mnt/home/someone/something/subdir:
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/subdir/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/subdir/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/subdir/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/subdir/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/subdir/e

Я хочу команду, которая будет находить все символические ссылки и ссылаться на те же места, но под /mnt/home вместо /home

Существует ли такая команда?

55
Josh

Нет команды для перенацеливания символической ссылки, все, что вы можете сделать, это удалить ее и создать другую. Предполагая, что у вас есть GNU утилиты (например, под не встроенным Linux или Cygwin), вы можете использовать -lname основной из find для сопоставления символических ссылок по их цели и readlink для чтения содержимого ссылки. Непроверенные:

find /mnt/home/someone/something -lname '/home/someone/*' \
     -exec sh -c 'ln -snf "/mnt$(readlink "$0")" "$0"' {} \;

Было бы лучше сделать эти символические ссылки относительными. Есть удобная небольшая утилита под названием symlinks (первоначально от Mark Lords, теперь поддерживаемая J. Brandt Buckley), присутствующая во многих дистрибутивах Linux. Перед перемещением или после восстановления действительных ссылок, как указано выше, запустите symlinks -c /mnt/home/someone/something для преобразования всех абсолютных символических ссылок в указанном каталоге в относительные символические ссылки, если они не пересекают границу файловой системы.

57

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

Следующее должно помочь, если требуется более гибкое решение, такое как наличие множества неработающих символических ссылок, которые можно исправить, заменив часть целей символической ссылки.

например. После изменения имени пользователя заменить старое имя пользователя новым именем пользователя в качестве цели для многих ссылок после того, как перемещение уже было сделано. Создайте скрипт под названием replace-simlinks, показанный ниже:

#!/bin/bash
link=$1
# grab the target of the old link
target=$(readlink -- "$1")

# replace the first occurrence of oldusername with newusername in the target string
target=${target/oldusername/newusername}

# Test the link creation
echo ln -s -- "$target" "$link"

# If the above echo shows the correct commands are being issued, then uncomment the following lines and run the command again
#rm "$link"
#ln -s "$target" "$link"

и вызовите его с помощью следующей команды:

find /home/newusername/ -lname '/home/oldusername/*' -exec ~/bin/replace-simlinks {} \;

Надеюсь, это поможет кому-нибудь

edit: Спасибо Gilles за кикстарт этого сценария и подсказку об использовании сценария символических ссылок, чтобы сделать ссылки относительными.

13
Gerry

Создайте /home как символическая ссылка на /mnt/home, и все существующие символические ссылки снова будут действительны.

4
Keith Thompson