Encontre todos os links simbólicos para um diretório e altere o destino para outro diretório

6

Eu tenho um monte de links simbólicos em /home para arquivos e subdiretórios em /foo . Quero segmentar o novo diretório, /bar .

Minha abordagem era examinar todos os links simbólicos inválidos e verificar se eles estavam apontando para /foo . Eu então fiz o seguinte:

sudo find . -type l -! -exec test -e {} \; -exec sh -c '\
   old_link_target=$(readlink "$0"); \
   new_link_target=${old_link_target//foo/bar}; \
   ln -snf $new_link_target $0' {} \;

No entanto, quero uma abordagem mais precisa que não inclua o passo inicial de colocar os olhos nos links simbólicos inválidos. Então, por causa dessa questão, suponha que /foo ainda exista, então outra abordagem é necessária.

    
por Belmin Fernandez 19.08.2014 / 14:52

2 respostas

8

GNUly:

find . -lname '/foo*' -printf '%p
find . -lname '/foo*' -printf '%l
find . -lname '/foo*' -print0 |
  tar --null -T - -cf - --transform='s@^/foo@/bar@' |
  tar xpf -
%p
find . -lname '/foo*' -printf '%p
find . -lname '/foo*' -printf '%l
find . -lname '/foo*' -print0 |
  tar --null -T - -cf - --transform='s@^/foo@/bar@' |
  tar xpf -
%p%pre%' | sed -z 's|^/foo|/bar|;n' | xargs -r0n2 ln -sfT
%l%pre%' | awk -vRS='%pre%' ' { getline target sub("^/foo", "/bar", target) printf("%s%pre%%s%pre%", target, $0) }' | xargs -r0n2 ln -sfT
' | sed -z 's|^/foo|/bar|;n' | xargs -r0n2 ln -sfT
%l%pre%' | awk -vRS='%pre%' ' { getline target sub("^/foo", "/bar", target) printf("%s%pre%%s%pre%", target, $0) }' | xargs -r0n2 ln -sfT

Ou com o% GNU sed :

%pre%

Cuidado com o fato de você estar potencialmente afetando a propriedade dos links simbólicos (assim, por exemplo, o autor original não poderá mais removê-los se eles estiverem em um diretório que eles não possuam, mas tiverem acesso de gravação a e tem o t bit set (como /tmp )).

Para evitar isso, você pode usar o GNU tar :

%pre%     
por 19.08.2014 / 15:11
0

Aqui está um pequeno conjunto de testes:

mkdir ./tmp1 ./tmp2    
touch ./tmp1/file1 ./tmp2/file2
ln -s ./tmp1 ./tmp3
ls -H ./tmp3

OUTPUT

file1

Então agora eu vou ...

mount --bind ./tmp2 ./tmp1
ls -H ./tmp3

OUTPUT

file2

tada! Agora todos os links que antes apontavam para ./tmp1 apontariam automaticamente para ./tmp2 - como, de fato, o mesmo acontece com ./tmp1 porque eles são o mesmo ponto de montagem. Tinha ./tmp2 contido montagens de crianças que eu poderia ter feito:

mount --rbind ./tmp2 ./tmp1

E recursivamente --bind mount das árvores. E isso não afeta nem mesmo a superfície das subárvores compartilhadas do kernel do Linux mount opções.

Em um sistema Linux, você não precisa se preocupar muito com o diretório para o qual um arquivo aponta, porque você pode afetar atomicamente a localização desse arquivo usando a árvore de montagem do sistema de arquivos virtual do kernel - ele está à sua disposição. E você pode gerenciar tudo em /etc/fstab .

>>/etc/fstab \
printf '%s %s none bind,defaults 0 0\n' \
    "/bar" "/foo"

E seus problemas estão resolvidos.

    
por 20.08.2014 / 01:20

Tags