Converta um hardlink em um link simbólico

3

É fácil converter um link simbólico em um link físico com ln -f ( exemplo )

Também seria fácil converter um link físico (nomes de arquivos link e original ) de volta para um link simbólico para link->original no caso em que você conhece os dois arquivos e define a si mesmo qual é o "arquivo original" . Você poderia facilmente criar um script simples convert-known-hardlink-to-symlink que resultaria em algo como:

convert-known-hardlink-to-symlink link original
$ ls -li
3802465 lrwxrwxrwx 1 14 Dec  6 09:52 link -> original
3802269 -rw-rw-r-- 1  0 Dec  6 09:52 original

Mas seria muito útil se você tivesse um script onde pudesse definir um diretório de trabalho (padrão ./ ) e um diretório de pesquisa onde procurar ( padrão / ) para arquivos com o mesmo inode e depois converter todos esses links para links simbólicos.

O resultado seria que no diretório de trabalho definido todos os arquivos que são hard-links são substituídos por links simbólicos para o primeiro arquivo encontrado com o mesmo inode.

Uma partida seria find . -type f -links +1 -printf "%i: %p (%n)\n"

    
por rubo77 06.12.2014 / 10:07

2 respostas

4

Eu criei um script que fará isso. O script converte todos os hard-links que encontrar em um diretório de origem (primeiro argumento) que são os mesmos que no diretório de trabalho (segundo argumento opcional) em links simbólicos:

link

Tem uma opção -n para um dry-run, que não faz nada além de mostrar o que seria feito.

Parte principal:

$WORKING_DIR=./
#relative source directory from working directory:
$SOURCE_DIR=../otherdir/with/hard-links/with-the-same-inodes

# find all files in WORKING_DIR
cd "$WORKING_DIR"
find "." -type f -links +1 -printf "%i %p\n" | \
  while read working_inode working_on
do
    find "$SOURCE_DIR" -type f -links +1 -printf "%i %p\n" | sort -nk1 | \
      while read inode file
    do
        if [[ $inode == $working_inode ]]; then
            ln -vsf "$file" "$working_on"
        fi
    done
done

Os -links +1 - > Vai encontrar todos os arquivos que possuem mais de um link. Os arquivos com link físico têm uma contagem de links de pelo menos dois.

    
por 06.12.2014 / 13:05
1

Pelo menos, GNU find também permite pesquisar por Inode, seja numérico ( -inode ) ou especificando o link ( -samefile ).

Então você pode usar:

find "$WORKING_DIR" -type f -links +1 | while read file
do
  find "$SOURCE_DIR" -samefile "$file" -exec ln -vsf '{}' "$file" \;
done

Você só precisa se certificar de usar diretórios separados. Por outro lado, ln reclamaria se você tentasse vincular um arquivo a ele mesmo.

Além disso, você deve fornecer um caminho absoluto para $SOURCE_DIR ou usar a opção -r com ln para criar links relativos, caso contrário, os links podem se tornar corrompidos.

    
por 20.10.2015 / 18:19