Преобразуйте абсолютную символьную ссылку на относительную символьную ссылку с простой командой Linux

Существует

ip route get 74.125.137.100

но это не делает разрешения сетевых имен (который я думаю, хорошая вещь). Команда обычно доступна от iproute или iproute2 пакетов.

29
13.11.2013, 11:53
6 ответов

С symlinks утилита Mark Lord (предлагаемый многими дистрибутивами; если Ваш не имеет его, создают его из источника):

chroot /home/user/system symlinks -cr .

С другой стороны, в системах, которые имеют a readlink команда и a -lname предикат к find (предупреждение: непротестированный код):

cd /home/user/system &&
find . -lname '/*' -exec ksh -c '
  for link; do
    target=$(readlink "$link")
    link=${link#./}
    root=${link//+([!\/])/..}; root=${root#/}; root=${root%..}
    rm "$link"
    ln -s "$root${target#/}" "$link"
  done
' _ {} +
21
27.01.2020, 19:38
  • 1
    Это было бы хорошим решением! Однако, что делает выражение _ {} + средний в конце находки? Кроме того, я получаю ошибку find: paths must precede expression: ksh который, кажется, не имеет смысл (поскольку путь предшествует ksh выражению). –  Alex 13.11.2013, 09:34
  • 2
    @Alex _ $0 для отрывка оболочки, и {} + заменяется списком аргументов, которые становятся $1, $2, и т.д., который for link; do … циклы по (это синонимично с for link in "$@"; do …). Ошибка от find происходит из-за опечатки (мне так или иначе удалось ввести одинарные левые кавычки вместо одинарных кавычек вокруг аргумента -lname). –  Gilles 'SO- stop being evil' 13.11.2013, 10:21
  • 3
    Теперь выполнения сценария, но не делает как ожидалось. Возможно, я не был достаточно точен, я обновил вопрос. –  Alex 13.11.2013, 11:56
  • 4
    @Alex, Какова проблема? Я думаю, что принцип является звуковым, но я, возможно, сделал некоторые ошибки кодирования. Вы пробовали symlinks? Это решило бы Вашу проблему — это в основном, для чего это было разработано (с раздражением, которое необходимо выполнить, это chrooted (fakechroot должен добиться цели)). –  Gilles 'SO- stop being evil' 13.11.2013, 12:00
  • 5
    я сильно предпочитаю решение, работающее из поля без потребности установить что-то дополнительное. –  Alex 13.11.2013, 12:02

Этот отрывок удара должен сделать это. Первая форма распечатает то, что она сделала бы; второе сделает это. Я тщательно рассмотрел бы вывод, поскольку это является разрушительным - ln -f перезаписывает существующую ссылку.

TOP=/home/user/system
cd $TOP
find * -type l -print | while read l; do echo ln -sf $TOP$(readlink $l) $l; done
find * -type l -print | while read l; do      ln -sf $TOP$(readlink $l) $l; done
0
27.01.2020, 19:38

Вот чистое решение sh.

cd /home/user/system &&
find . -lname '/*' |
while read l ; do
  echo ln -sf $(echo $(echo $l | sed 's|/[^/]*|/..|g')$(readlink $l) | sed 's/.....//') $l
done |
sh
0
27.01.2020, 19:38

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

Команда :Там

sudo sshfs <remote_user>@<remote_ip_address>:/ /home/<host_user>/mntpoint/ -o transform_symlinks -o allow_other

Команда, особенно <placeholders>, должна быть адаптирована к конкретной среде.

3
27.01.2020, 19:38

Чистый bash и coreutils, изменяет символические ссылки на относительные без лишних ../s в пути:

find. -type l | while read l; do
    target="$(realpath "$l")"
    ln -fs "$(realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target")" "$l"
done

Вы можете изменить:

  • find.в find /path/to/directoryдля преобразования символических ссылок в этом каталоге
  • с
  • ln -fsпо echo ln -fsдля пробного прогона

Пояснение:

  • target="$(realpath "$l")"-находит абсолютный путь к цели символической ссылки
  • ln -fs-создает символическую ссылку (-s), заставляя(-f)перезаписывать существующие
  • realpath -s "$l"-находит абсолютный путь к самой символической ссылке
  • dirname "$(realpath -s "$l")"-находит абсолютный путь к каталогу, содержащему символическую ссылку
  • realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"-находит путь к цели относительно символической ссылки, другими словами :преобразует абсолютный путь в относительный
5
27.01.2020, 19:38
find -lname "$PWD/*" | while read link ;do  
   target=$(readlink $link);
   relative_target=$(realpath $target --relative-to=$link/.. --no-symlinks --canonicalize-missing);
   ln --force --symbolic --no-target-directory $relative_target $link
done

"$PWD/*"означает преобразование только абсолютных ссылок, которые указывают внутри текущего рабочего каталога

0
27.01.2020, 19:38

Теги

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