У меня есть полный суб-файловая система внутри пути , /home/user/system
содержащие стандартную структуру Linux с каталогами /bin
, /home
, /root
, /usr
, /var
, /etc
, ...
Эта субфайловая система содержит символические ссылки, относительные или абсолютные. Относительные символические ссылки просто хороши, они остаются внутри подсистемы /home/user/system
. Но абсолютные символические ссылки проблематичны, так как они указывают на цель вне субфайловой системы.
В качестве примера мы предполагаем абсолютную символическую ссылку следующим образом (видно внутри подсистемы файлов):
/usr/file1 -> /usr/lib/file1
В общей файловой системе у нас есть ссылка /home/user/system/usr/file1
, указывающая на файл /usr/lib/file1
вне субфайловой системы, а не на файл /home/user/system/usr/lib/file1
внутри субфайловой системы.
Я хотел бы иметь простой скрипт, предпочтительно единственную командную строку (rsync, chroot, find, ...), которая преобразует каждую абсолютную символическую ссылку в относительную.
В данном примере эта относительная ссылка станет
/usr/file1 -> ../usr/lib/file1
источник
Ответы:
С помощью
symlinks
утилиты от Mark Lord (предлагается во многих дистрибутивах; если у вас ее нет, соберите ее из исходного кода ):Альтернативно, в системах, которые имеют
readlink
команду и-lname
предикатfind
(предупреждение: непроверенный код):источник
_ {} +
в конце находки? Кроме того, я получаю ошибку,find: paths must precede expression: ksh
которая, кажется, не имеет смысла (так как путь предшествует выражению ksh)._
является$0
для сниппета оболочки, и{} +
заменяется список аргументов , которые становятся$1
,$2
и т.д. , которыеfor link; do …
перебирают (это синонимfor link in "$@"; do …
). Ошибка из-find
за опечатки (мне как-то удалось набрать обратные кавычки вместо одинарных кавычек вокруг аргумента-lname
).symlinks
? Это решило бы вашу проблему - это в основном то, для чего оно было разработано (с досадой, что вы должны запускать его chroot ( fakechroot должен сделать свое дело)).Pure bash & coreutils, меняет символические ссылки на относительные без ненужных
../
s в пути:Ты можешь измениться:
find .
чтобыfind /path/to/directory
преобразовать символические ссылки в этом каталогеln -fs
вecho ln -fs
течение сухого ходаОбъяснение:
target="$(realpath "$l")"
- находит абсолютный путь к цели символической ссылкиln -fs
- создает symlink (-s
), заставляет (-f
) переписывать существующиеrealpath -s "$l"
- находит абсолютный путь к самой символической ссылкеdirname "$(realpath -s "$l")"
- находит абсолютный путь к каталогу, содержащему символическую ссылкуrealpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"
- находит путь цели относительно символической ссылки, другими словами: преобразует абсолютный путь в относительный путьисточник
if
пункт, чтобы пропустить неработающие ссылки.Этот фрагмент кода должен сделать это. Первая форма напечатает, что она будет делать; второй сделает это. Я бы внимательно рассмотрел вывод, поскольку он разрушительный -
ln -f
перезаписывает существующую ссылку.источник
Вот чистое решение.
источник
Преобразование абсолютного в относительные ссылки поддерживается sshfs, который монтирует удаленные каталоги через ssh.
Команда: Там
Команда, особенно
<placeholders>
, должна быть адаптирована к конкретной среде.источник