Links Simbólicos e Hard Links - Entendendo Referências de Arquivo no Linux

Links Simbólicos e Hard Links - Entendendo Referências de Arquivo no Linux

A Resposta Curta

Um link simbólico armazena uma string de caminho (como um atalho); um hard link é uma entrada de diretório adicional apontando para o mesmo inode (os mesmos dados com um nome diferente). Na dúvida, use um link simbólico (ln -s).

Quando usar qual

  • Links entre sistemas de arquivos, ou links para diretórios --> link simbólico
  • Backups incrementais onde originais excluídos não devem destruir dados --> hard link
  • Não tem certeza --> link simbólico

Sintaxe do Comando ln

O comando ln cria tanto links simbólicos 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 diretório, falhará com um erro, mas para arquivos regulares o erro passa despercebido.

Um link simbólico é 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 início da string de permissões indica um symlink. A -> mostra o caminho armazenado.

Propriedade Detalhes
Entre sistemas de arquivos Sim (diferentes pontos de montagem OK)
Link para diretório Sim
Se o alvo for excluído O link fica pendente (quebrado)
Resolução Caminho é 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 é uma entrada de diretório 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 número inicial (1234567) é o número do inode -- números idênticos significam dados idênticos. A contagem de links (2) mostra quantas entradas de diretório referenciam este inode.

Propriedade Detalhes
Entre sistemas de arquivos Não (mesma partição apenas)
Link para diretório Não (restrito para usuários regulares)
Se o original for excluído Dados persistem até contagem de links chegar a 0
Resolução Acesso direto ao inode (sem travessia de caminho)

Comparação: Symlink vs Hard Link

A diferença principal é o que cada um referência.

Aspecto Link Simbólico Hard Link
Referência String de caminho inode
Entre sistemas de arquivos Sim Não
Alvo diretório Sim Não
Após alvo excluído Fica pendente Dados sobrevivem
Permissões ls Começa com l Igual a arquivo regular
inode Próprio inode (separado) Mesmo inode do alvo

Casos de Uso Práticos

Gerenciamento de dotfiles

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

Diretório "current" gerenciado por versão

# 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 diretório, de modo que o link em si é substituído em vez de um novo link ser criado dentro do diretório.

Backups incrementais com rsync

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

Arquivos inalterados desde o backup anterior são hard-linked em vez de copiados, então o snapshot de cada dia é eficiente em espaço 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 você passou para ln -- não um caminho relativo a onde o arquivo de link reside. Use caminhos absolutos para symlinks que devem funcionar de múltiplas localizações.

# 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 não existe (-type l sozinho inclui todos os symlinks, tanto válidos quanto quebrados).

Próximas Leituras