Eu tenho um sub-sistema de arquivos completo dentro de um caminho /home/user/system
que contém a estrutura padrão do Linux com diretórios /bin
, /home
, /root
, /usr
, /var
, /etc
, ...
Este sub-sistema de arquivos contém links simbólicos, relativos ou absolutos. Os links simbólicos relativos são ótimos, eles ficam no sub-sistema de arquivos abaixo /home/user/system
. Mas links simbólicos absolutos são problemáticos, pois apontam para um alvo fora do sistema de subarquivos.
Como exemplo, assumimos um link simbólico absoluto da seguinte maneira (visto dentro do sub-sistema de arquivos):
/usr/file1 -> /usr/lib/file1
No sistema de arquivos geral, temos um link /home/user/system/usr/file1
que agora aponta para um arquivo /usr/lib/file1
fora do sub-sistema de arquivos, em vez de um arquivo /home/user/system/usr/lib/file1
dentro do sub-sistema de arquivos.
Eu gostaria de ter um script simples, de preferência uma única linha de comando (rsync, chroot, find, ...) que converta cada link simbólico absoluto para um relativo.
No exemplo dado, esse link relativo se tornaria
/usr/file1 -> ../usr/lib/file1
fonte
Respostas:
Com o
symlinks
utilitário Mark Lord (oferecido por muitas distribuições; se o seu não tiver, crie-o a partir da fonte ):Como alternativa, em sistemas que possuem um
readlink
comando e um-lname
predicado parafind
(aviso: código não testado):fonte
_ {} +
significa no final da descoberta? Além disso, recebo um errofind: paths must precede expression: ksh
que parece não fazer sentido (como o caminho precede a expressão ksh)._
é$0
para o trecho shell, e{} +
é substituída pela lista de argumentos que se tornam$1
,$2
etc., quefor link; do …
faz um loop sobre (é sinônimo defor link in "$@"; do …
). O erro defind
é devido a um erro de digitação (de alguma forma, consegui digitar aspas simples em vez de aspas simples ao redor do argumento-lname
).symlinks
? Isso resolveria o seu problema - é basicamente para isso que ele foi projetado (com o incômodo de ter que executá-lo com chroot (o fakechroot deve fazer o truque)).Pure bash & coreutils, altera links simbólicos para parentes sem
../
s desnecessários no caminho:Você pode mudar:
find .
parafind /path/to/directory
converter links simbólicos nesse diretórioln -fs
aecho ln -fs
para uma corrida secaExplicação:
target="$(realpath "$l")"
- encontra o caminho absoluto para o destino do link simbólicoln -fs
- cria ligação simbólica (-s
), forçando (-f
) a reescrever as existentesrealpath -s "$l"
- encontra o caminho absoluto para o próprio link simbólicodirname "$(realpath -s "$l")"
- localiza o caminho absoluto para o diretório que contém o link simbólicorealpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"
- localiza o caminho do destino em relação ao link simbólico, em outras palavras: converte absoluto em caminho relativofonte
if
cláusula para pular links quebrados.Esse snippet do bash deve fazer isso. O primeiro formulário imprimirá o que faria; o segundo fará isso. Eu analisaria cuidadosamente a saída, pois é destrutiva -
ln -f
substitui o link existente.fonte
Aqui está uma solução sh pura.
fonte
A transformação absoluta em links relativos é suportada pelo sshfs, que monta diretórios remotos via ssh.
O comando é: Não
O comando, especialmente o
<placeholders>
, deve ser adaptado ao ambiente específico.fonte