realpath e readlink: Resolvendo Caminhos Absolutos e Symlinks
O Que Voce Vai Aprender
- A diferenca entre
realpathereadlink, e quando usar cada um - Como resolver symlinks e segmentos
..em um caminho absoluto - Os tres niveis de verificacao de existencia por tras de
-f/-e/-m - Como escrever resolucao segura de caminhos em shell scripts
Resumo Rapido
- Quer um caminho absoluto -->
realpath path - Quer ver para onde um symlink aponta -->
readlink link - Quer seguir cada link e
..ate um unico 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 padrao a partir do coreutils 8.15- Comportamento neste artigo verificado no coreutils 9.4
Qual e a diferenca entre realpath e readlink?
Conclusao:
readlinkle o conteudo 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 sao proximos em nome e proposito, mas seu comportamento basico difere.
| Aspecto | readlink (sem opcoes) |
realpath (sem opcoes) |
|---|---|---|
| Proposito principal | Ler a string de destino do link | Calcular o caminho absoluto real |
| Alvo nao e um symlink | Nao imprime nada, falha | Retorna o caminho absoluto |
| Destino do link e relativo | Mantido como a string relativa armazenada | Resolvido para caminho absoluto |
Resolucao de .. |
Nao | Sim |
O ponto principal: readlink sozinho e apenas para symlinks. Execute em um arquivo regular ou diretorio e ele falha silenciosamente (veja armadilhas abaixo). realpath, por outro lado, retorna um caminho absoluto para qualquer caminho.
Como usar readlink?
Conclusao:
readlinksozinho imprime o destino do link como armazenado. Adicione-fe ele segue links recursivamente e retorna o caminho absoluto final.
Mostrar o conteudo do link (sem opcoes)
readlink imprime a string armazenada dentro de um symlink. Na maioria dos sistemas, /bin e um link relativo para usr/bin.
$ readlink /bin
usr/bin
Como o valor armazenado e relativo (usr/bin), a saida permanece relativa, e .. nao e 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 familia -f tem tres modos que diferem em quao rigorosa e a verificacao de existencia.
| Opcao | Forma longa | Requisito de existencia |
|---|---|---|
-f |
--canonicalize |
Todos exceto o ultimo 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 voce esta 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. Substituicao de comando $(...) ja remove quebras de linha finais, entao raramente e necessario la, mas ajuda ao concatenar com printf.
Como usar realpath?
Conclusao:
realpath pathretorna o caminho absoluto com todos os symlinks,..e.resolvidos. Seu padrao corresponde areadlink -f: todos exceto o ultimo componente devem existir.
Resolver links e caminhos relativos em um unico caminho real
$ realpath /bin
/usr/bin
Diferente de readlink, realpath tambem funciona em caminhos que nao sao symlinks -- essa e a grande diferenca pratica.
$ cd /var/log $ realpath ../tmp
/var/tmp
.., . e barras duplicadas sao todos normalizados.
Controlar a verificacao de existencia (-e / -m)
realpath usa os mesmos tres niveis que readlink.
- Padrao: todos exceto o ultimo 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
Alem de caminhos absolutos, realpath tambem pode calcular um caminho relativo a um diretorio base.
$ realpath --relative-to=/home /home/alice/work/report.txt
alice/work/report.txt
Util em scripts que precisam de uma posicao relativa a um diretorio de configuracao. --relative-base=DIR mantem o resultado relativo apenas quando o alvo esta sob DIR, e absoluto caso contrario.
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 sao as armadilhas comuns?
Conclusao: A maior armadilha e que
readlinksozinho falha silenciosamente em arquivos regulares. Para resolucao de caminhos em scripts, userealpathoureadlink -f.
1. readlink sozinho em arquivo regular retorna vazio
readlink (sem opcoes) nao imprime nada e retorna exit 1 para qualquer coisa que nao seja um symlink.
$ readlink /etc/hostname # sem saida, exit 1 (/etc/hostname e um arquivo regular)
Escrito em um script, isso deixa uma variavel vazia quando o alvo nao e um symlink -- uma forma facil 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 voce quer resolver um caminho de saida que ainda nao existe, -e vai falhar. Para um caminho que voce esta prestes a criar, escolha -f (ultimo 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 diretorio que ele referencia, nao para o link em si. Isso pode mudar silenciosamente o resultado resolvido, entao omita a barra final / quando quiser inspecionar o link em si.
Regra pratica
- Ver a string de destino um nivel -->
readlink link - Precisa do caminho absoluto real (scripts incluidos) -->
realpath pathoureadlink -f path - Garantir existencia -->
-e - Calcular um caminho que voce vai criar -->
-fou-m
Um exemplo pratico em script
Conclusao: Resolver o diretorio real de instalacao de um script e o caso de uso classico para
realpath/readlink -f. Mesmo quando iniciado atraves de um symlink, voce obtem o diretorio real.
Shell scripts frequentemente precisam referenciar outros arquivos relativos a sua propria localizacao. realpath resolve a localizacao real mesmo quando o script e invocado atraves 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 minimos sem realpath, readlink -f "$0" e a alternativa direta. Ambos usam por padrao o mesmo comportamento "todos exceto o ultimo componente devem existir".
Sistemas baseados em BSD como macOS vem com um readlink sem -f (ou com comportamento diferente). Para scripts portaveis que nao podem assumir GNU coreutils, verifique se realpath existe, ou use o idioma cd "$(dirname "$0")" && pwd como fallback.