Qual é a diferença entre "caminho real" e "readlink -f"

68

Eu li muito sobre o realpathcomando e como ele foi descontinuado com o readlink -fque agora é recomendado. Também vi em alguns lugares que a razão pela qual o realpath foi introduzido foi pela falta de tal funcionalidade no readlink e que, uma vez introduzida, o realpath não era mais necessário e seu suporte foi descontinuado pela maioria dos fornecedores de sistemas operacionais.

O motivo da minha pergunta é que eu também vi muitas pessoas recomendando readlink -fcomo um comando "bem parecido" realpath, e é isso que está me incomodando, porque ninguém detalha essa parte "muito parecida". Quais são as diferenças reais?

Felipe Leão
fonte

Respostas:

73

Existem vários realpathcomandos por aí.

O realpathutilitário é um invólucro em torno das realpathfunções da biblioteca e foi reinventado várias vezes .

Debian usado para manter um realpathpacote ( separados a partir dwwwdesde lenhosa ), que não mudou, exceto sobre embalagens e documentação desde 2001, mas agora foi descontinuada. Este utilitário foi descontinuado porque agora existem mais alternativas padrão (GNU readlinke logo GNU realpath), mas, na época, os utilitários GNU nem sequer possuíam readlink. Esta implementação realpathsuporta alguns optionspara impedir a resolução de link simbólico ou produzir saída terminada em nulo. O BusyBox também inclui seu próprio realpathcomando (que não tem opção).

O GNU coreutils introduziu um realpathcomando na versão 8.15 em janeiro de 2012. Este é um substituto compatível para o BusyBox e o Debian realpathe também possui muitas opções em comum com o GNU readlink.

realpathtem o mesmo efeito que readlink -fcom o GNU readlink. O que distingue os dois comandos (ou melhor, os vários realpathcomandos readlink -f) são as opções extras que eles suportam.

GNU realpathnão está obsoleto; tem o problema oposto: é novo demais para estar disponível em qualquer lugar. O Debian costumava omitir o GNUrealpath do seu coreutilspacote e manter o seu realpath. Não sei por que, já que o GNU realpathdeve ser um substituto. No Debian jessie e no Ubuntu 16.04, no entanto, o GNU realpathé usado.

Nos sistemas Linux, no momento, sua melhor opção para canonizar um caminho que pode conter links simbólicos é readlink -f.

Os sistemas BSD têm um readlinkcomando, com diferentes recursos do GNU readlink. Em particular, o BSD readlinknão tem uma opção para canonizar caminhos, apenas percorre o link simbólico passado a ele.

readlink, aliás, teve o mesmo problema - ele também foi inventado várias vezes (não adicionar esse utilitário quando links simbólicos foram adicionados ao Unix foi uma omissão lamentável). Agora, ele se estabilizou em várias implementações com muitos sinalizadores incompatíveis (em particular BSD vs. GNU).

Gilles 'SO- parar de ser mau'
fonte
8
readlink -festava no OpenBSD muito antes do GNU. Todo o NetBSD, FreeBSD e OpenBSD agora possuem readlink -f(o seu link até menciona). realpathestá no FreeBSD e no IRIX há muito tempo (não sei se é anterior ao Debian). HPUX e IRIX também têm readlink, embora não -f. O realpathpacote no Debian experimental agora é o do coreutils (como um experimento para ver se ele quebra as coisas). O dwww realpathage mais como readlink -eenquanto o GNU um como readlink -fpor isso não é um dropin completa substituir
Stéphane Chazelas
2
realpathtem sido no FreeBSD desde 2002. Antes disso, pwdestava fazendo isso (desde 2000, pwd some-filechamaria realpath()on file). Debian teve um realpathpacote desde 1996. A uma, IRIX provavelmente antecede-lo embora eu não encontrei nenhuma outra prova do que era no IRIX 6.5 em 1998. OpenBSD adicionou um -fa readlink em 1997 . O GNU foi adicionado readlinkem 2003 e possuía -fdesde o início.
Stéphane Chazelas
2
Excelente resumo obrigado. Nota uma melhor bug para o pedido de debian para mudar para a variante GNU é bugs.debian.org/730779 Mesmo o mantenedor realpath existente quer o interruptor de acontecer
Pádraig Brady
11
Resposta incrível. Faltou apenas referências à implementação de RHEL de realpath. Alguém sabe se é de alguma forma diferente da readlink -fversão?
Felipe Leão
11
@ StéphaneChazelas Oh, uau, muitos erros nas minhas respostas, de fato. Obrigado por apontá-los. Você poderia postar uma resposta correta e eu excluirei a minha? (Caso contrário, corrigirei os erros, mas é mais trabalho seguir minha longa lista de tarefas…)
Gilles 'SO- deixa de ser mau'
17

tl; dr readlink -f retornará 0para um arquivo inexistente em um diretório existente, enquanto realpathretorna 1. No entanto, readlink -ese comportará como realpathe retornará 1para um arquivo inexistente (consulte a nota do editor no final).

readlink -f

$ readlink -f non-existent-file
/home/user/non-existent-file
$ echo $?
0

readlink -e

$ readlink -e non-existent-file
$ echo $?
1

realpath

$ realpath non-existent-file
non-existent-file: No such file or directory
$ echo $?
1

readlink -f com diretório inexistente

readlink -f o comportamento varia dependendo de qual parte do caminho não existe.

$ readlink -f /tmp/non-existent-dir/foo
$ echo $?
1

Disponibilidade

readlinkestá instalado na maioria das distribuições Linux. Visto realpathque muitas vezes deve ser explicitamente instalado.

Em suma

Se você deseja substituir as chamadas realpath ..., use readlink -e ....


Testado com readlink (GNU coreutils) 8.21 e realpath versão 1.19 no Ubuntu 16.

( Ed .: @AnthonyGeoghegan escreveu " isso se refere à versão Debian de realpath. A versão GNU do realpathcomporta-se da mesma forma quereadlink -f ")

JamesThomasMoon1979
fonte
3
Votei positivamente nesta resposta, mas sugiro esclarecer que isso se refere à versão Debian de realpath. A versão GNU do realpathcomporta-se da mesma forma que readlink -f.
Anthony G - justice para Monica
2
Pode confirmar que isso não funciona no MacOS High Sierra.
Pred