Links Simbolicos e Hard Links - Entendendo Referencias de Arquivo no Linux

Links Simbolicos e Hard Links - Entendendo Referencias de Arquivo no Linux

A Resposta Curta

Um link simbolico armazena uma string de caminho (como um atalho); um hard link e uma entrada de diretorio adicional apontando para o mesmo inode (os mesmos dados com um nome diferente). Na duvida, use um link simbolico (ln -s).

Quando usar qual

  • Links entre sistemas de arquivos, ou links para diretorios --> link simbolico
  • Backups incrementais onde originais excluidos nao devem destruir dados --> hard link
  • Nao tem certeza --> link simbolico

Sintaxe do Comando ln

O comando ln cria tanto links simbolicos quanto hard links.

# Link simbolico (-s e obrigatorio)
ln -s [alvo] [nome_do_link]

# Hard link (sem -s)
ln [alvo] [nome_do_link]

Omitir -s silenciosamente cria um hard link. Se o alvo for um diretorio, falhara com um erro, mas para arquivos regulares o erro passa despercebido.

Um link simbolico e um arquivo especial que armazena uma string de caminho. O SO resolve esse caminho a cada acesso -- similar a um atalho do Windows, mas tratado de forma transparente pelo kernel.

$ ln -s /etc/nginx/nginx.conf ./nginx.conf
$ ls -la
lrwxrwxrwx 1 user user 22 Jan  1 00:00 nginx.conf -> /etc/nginx/nginx.conf

O l no inicio da string de permissoes indica um symlink. A -> mostra o caminho armazenado.

Propriedade Detalhes
Entre sistemas de arquivos Sim (diferentes pontos de montagem OK)
Link para diretorio Sim
Se o alvo for excluido O link fica pendente (quebrado)
Resolucao Caminho e resolvido novamente a cada acesso
# Mostrar o caminho armazenado
$ readlink nginx.conf
/etc/nginx/nginx.conf

# Resolver para caminho absoluto
$ readlink -f nginx.conf
/etc/nginx/nginx.conf

Um hard link e uma entrada de diretorio adicional apontando para o mesmo inode. Ambos os nomes se referem exatamente aos mesmos dados -- um inode, dois nomes.

$ echo "hello" > original.txt
$ ln original.txt hardlink.txt
$ ls -lai
1234567 -rw-r--r-- 2 user user 6 Jan  1 00:00 hardlink.txt
1234567 -rw-r--r-- 2 user user 6 Jan  1 00:00 original.txt

O numero inicial (1234567) e o numero do inode -- numeros identicos significam dados identicos. A contagem de links (2) mostra quantas entradas de diretorio referenciam este inode.

Propriedade Detalhes
Entre sistemas de arquivos Nao (mesma particao apenas)
Link para diretorio Nao (restrito para usuarios regulares)
Se o original for excluido Dados persistem ate contagem de links chegar a 0
Resolucao Acesso direto ao inode (sem travessia de caminho)

Comparacao: Symlink vs Hard Link

A diferenca principal e o que cada um referencia.

Aspecto Link Simbolico Hard Link
Referencia String de caminho inode
Entre sistemas de arquivos Sim Nao
Alvo diretorio Sim Nao
Apos alvo excluido Fica pendente Dados sobrevivem
Permissoes ls Comeca com l Igual a arquivo regular
inode Proprio inode (separado) Mesmo inode do alvo

Casos de Uso Praticos

Gerenciamento de dotfiles

$ ln -s ~/dotfiles/.bashrc ~/.bashrc
$ ln -s ~/dotfiles/.vimrc ~/.vimrc

Diretorio "current" gerenciado por versao

# Apontar current para a versao 1.2.0
$ ln -s /opt/app-1.2.0 /opt/app/current

# Atualizar: reapontar o link atomicamente
$ ln -sfn /opt/app-1.3.0 /opt/app/current

-f sobrescreve um link existente; -n impede seguir um alvo diretorio, de modo que o link em si e substituido em vez de um novo link ser criado dentro do diretorio.

Backups incrementais com rsync

$ rsync -a --link-dest=/backup/prev/ /data/ /backup/today/

Arquivos inalterados desde o backup anterior sao hard-linked em vez de copiados, entao o snapshot de cada dia e eficiente em espaco enquanto permanece independente.

Armadilhas Comuns

# Criado de /home/user
$ ln -s ../etc/nginx/nginx.conf nginx.conf

# Quebra quando acessado de /tmp
$ cd /tmp
$ cat nginx.conf
cat: nginx.conf: No such file or directory

O symlink registra a string de caminho exata que voce passou para ln -- nao um caminho relativo a onde o arquivo de link reside. Use caminhos absolutos para symlinks que devem funcionar de multiplas localizacoes.

# Errado: se current for um diretorio, ln -sf cria um link DENTRO dele
$ ln -sf /opt/app-2.0.0 /opt/app/current

# Correto: -n substitui o link em si
$ ln -sfn /opt/app-2.0.0 /opt/app/current
$ find /path -maxdepth 1 -xtype l

-xtype l corresponde a symlinks cujo alvo nao existe (-type l sozinho inclui todos os symlinks, tanto validos quanto quebrados).

Proximas Leituras