realpath e readlink: Resolvendo Caminhos Absolutos e Symlinks
O Que Você Vai Aprender
- A diferença entre
realpathereadlink, e quando usar cada um - Como resolver symlinks e segmentos
..em um caminho absoluto - Os três níveis de verificação de existência por trás de
-f/-e/-m - Como escrever resolução segura de caminhos em shell scripts
Resumo Rápido
- Quer um caminho absoluto -->
realpath path - Quer ver para onde um symlink aponta -->
readlink link - Quer seguir cada link e
..até um único caminho real -->realpath pathoureadlink -f path - Em scripts, use
realpathoureadlink -f-- nuncareadlinksozinho
Premissas (ambiente alvo)
- GNU coreutils (Ubuntu / Debian / RHEL e a maioria das distros Linux comuns)
realpathvem como padrão a partir do coreutils 8.15- Comportamento neste artigo verificado no coreutils 9.4
Qual é a diferença entre realpath e readlink?
Conclusão:
readlinklê o conteúdo de um symlink (sua string de destino).realpathresolve um caminho inteiro em sua forma absoluta real. Adicionereadlink -fe ele se comporta quase exatamente comorealpath.
Os dois são próximos em nome e propósito, mas seu comportamento básico difere.
| Aspecto | readlink (sem opções) |
realpath (sem opções) |
|---|---|---|
| Propósito principal | Ler a string de destino do link | Calcular o caminho absoluto real |
| Alvo não é um symlink | Não imprime nada, falha | Retorna o caminho absoluto |
| Destino do link é relativo | Mantido como a string relativa armazenada | Resolvido para caminho absoluto |
Resolução de .. |
Não | Sim |
O ponto principal: readlink sozinho é apenas para symlinks. Execute em um arquivo regular ou diretório e ele falha silenciosamente (veja armadilhas abaixo). realpath, por outro lado, retorna um caminho absoluto para qualquer caminho.
Como usar readlink?
Conclusão:
readlinksozinho imprime o destino do link como armazenado. Adicione-fe ele segue links recursivamente e retorna o caminho absoluto final.
Mostrar o conteúdo do link (sem opções)
readlink imprime a string armazenada dentro de um symlink. Na maioria dos sistemas, /bin é um link relativo para usr/bin.
$ readlink /bin
usr/bin
Como o valor armazenado é relativo (usr/bin), a saída permanece relativa, e .. não é resolvido. Use isso quando quiser apenas saber para onde um link aponta.
Resolver completamente com -f / -e / -m
Adicione -f (--canonicalize) para seguir cada symlink no caminho, processar .. e retornar um caminho absoluto.
$ readlink -f /bin
/usr/bin
A família -f tem três modos que diferem em quão rigorosa é a verificação de existência.
| Opção | Forma longa | Requisito de existência |
|---|---|---|
-f |
--canonicalize |
Todos exceto o último componente devem existir |
-e |
--canonicalize-existing |
Todos os componentes devem existir |
-m |
--canonicalize-missing |
Nenhum precisa existir |
# Pai existe, apenas o arquivo final esta ausente --> -f funciona, -e falha $ readlink -f /etc/does-not-exist.conf /etc/does-not-exist.conf $ readlink -e /etc/does-not-exist.conf # nao imprime nada, exit 1
Use -f ou -m para calcular o caminho final de um arquivo que você está prestes a criar; use -e quando precisar garantir que o caminho existe.
Ao mostrar o destino de um link, -n (--no-newline) suprime a quebra de linha final. Substituição de comando $(...) já remove quebras de linha finais, então raramente é necessário lá, mas ajuda ao concatenar com printf.
Como usar realpath?
Conclusão:
realpath pathretorna o caminho absoluto com todos os symlinks,..e.resolvidos. Seu padrão corresponde areadlink -f: todos exceto o último componente devem existir.
Resolver links e caminhos relativos em um único caminho real
$ realpath /bin
/usr/bin
Diferente de readlink, realpath também funciona em caminhos que não são symlinks -- essa é a grande diferença prática.
$ cd /var/log $ realpath ../tmp
/var/tmp
.., . e barras duplicadas são todos normalizados.
Controlar a verificação de existência (-e / -m)
realpath usa os mesmos três níveis que readlink.
- Padrão: todos exceto o último componente devem existir (o pai deve ser real)
-e(--canonicalize-existing): cada componente deve existir-m(--canonicalize-missing): nenhum componente precisa existir
# Diretorio pai nao existe --> falha mesmo por padrao $ realpath /no-such-dir/file.txt realpath: /no-such-dir/file.txt: No such file or directory # -m normaliza e retorna mesmo um caminho totalmente ausente $ realpath -m /no-such-dir/file.txt /no-such-dir/file.txt
Converter para caminho relativo com --relative-to
Além de caminhos absolutos, realpath também pode calcular um caminho relativo a um diretório base.
$ realpath --relative-to=/home /home/alice/work/report.txt
alice/work/report.txt
Útil em scripts que precisam de uma posição relativa a um diretório de configuração. --relative-base=DIR mantém o resultado relativo apenas quando o alvo está sob DIR, e absoluto caso contrário.
Manter links intactos com -s
Adicione -s (--strip / --no-symlinks) para normalizar . e .. sem resolver symlinks. Use quando quiser organizar um caminho preservando a estrutura de links.
$ realpath -s /bin/../bin
/bin
Quais são as armadilhas comuns?
Conclusão: A maior armadilha é que
readlinksozinho falha silenciosamente em arquivos regulares. Para resolução de caminhos em scripts, userealpathoureadlink -f.
1. readlink sozinho em arquivo regular retorna vazio
readlink (sem opções) não imprime nada e retorna exit 1 para qualquer coisa que não seja um symlink.
$ readlink /etc/hostname # sem saida, exit 1 (/etc/hostname e um arquivo regular)
Escrito em um script, isso deixa uma variável vazia quando o alvo não é um symlink -- uma forma fácil de causar surpresas.
# Arriscado: p fica vazio se $f nao for um symlink p=$(readlink "$f") # Seguro: p contem um caminho absoluto para symlinks e arquivos regulares p=$(realpath "$f")
2. Confundir -f e -e
Se você quer resolver um caminho de saída que ainda não existe, -e vai falhar. Para um caminho que você está prestes a criar, escolha -f (último componente pode estar ausente) ou -m (tudo pode estar ausente).
3. Barra final em um symlink
Uma barra final / em um symlink aponta para o diretório que ele referência, não para o link em si. Isso pode mudar silenciosamente o resultado resolvido, então omita a barra final / quando quiser inspecionar o link em si.
Regra prática
- Ver a string de destino um nível -->
readlink link - Precisa do caminho absoluto real (scripts incluídos) -->
realpath pathoureadlink -f path - Garantir existência -->
-e - Calcular um caminho que você vai criar -->
-fou-m
Um exemplo prático em script
Conclusão: Resolver o diretório real de instalação de um script é o caso de uso clássico para
realpath/readlink -f. Mesmo quando iniciado através de um symlink, você obtém o diretório real.
Shell scripts frequentemente precisam referenciar outros arquivos relativos a sua própria localização. realpath resolve a localização real mesmo quando o script é invocado através de um symlink.
#!/bin/bash # Resolve the script's real directory script_path=$(realpath "$0") script_dir=$(dirname "$script_path") echo "Running script: $script_path" echo "Install dir: $script_dir" # Safely reference a config file next to the script config="$script_dir/config.env"
Em sistemas mínimos sem realpath, readlink -f "$0" é a alternativa direta. Ambos usam por padrão o mesmo comportamento "todos exceto o último componente devem existir".
Sistemas baseados em BSD como macOS vêm com um readlink sem -f (ou com comportamento diferente). Para scripts portáveis que não podem assumir GNU coreutils, verifique se realpath existe, ou use o idioma cd "$(dirname "$0")" && pwd como fallback.