`~ / Documents` é um caminho relativo ou absoluto?

37

Esta é apenas uma questão de vocabulário, mas que continua girando na minha cabeça.

Vem de um exame prático de um livro de preparação do LPIC . A resposta correta de acordo com o livro é que ~/Documentsé um diretório relativo, porque é relativo ao diretório inicial.

No entanto, este livro contém uma proporção honrosa de erros de digitação e, portanto, não posso tomar como certo tudo o que está escrito lá. Não concordo aqui porque, para mim, ~atua como uma variável expandida pelo shell no conteúdo da $HOMEvariável ou no caminho do diretório inicial do usuário atual (cf. man bash); portanto, o caminho real /home/myuser/Documentsé realmente um diretório absoluto.

Até a Wikipedia , por uma vez, não me ajuda em nada sobre esse assunto (mesmo que pareça confirmar que o livro está errado nesse assunto):

Um caminho absoluto ou completo aponta para o mesmo local em um sistema de arquivos, independentemente do diretório de trabalho atual. Para fazer isso, ele deve conter o diretório raiz.

Por outro lado, um caminho relativo inicia em um determinado diretório de trabalho, evitando a necessidade de fornecer o caminho absoluto completo.

Aqui, novamente, eu não concordo: de acordo com essa definição, o caminho /opt/kde3/bin/../libque não depende do diretório de trabalho atual deve ser absoluto, mas meu entendimento atual disso coincide com o autor do livro, tornando esse caminho relativo.

Uma rápida pesquisa na web está apenas aumentando minha frustração, de acordo com o Webster Dictionary :

caminho absoluto - Um caminho relativo ao diretório raiz. Seu primeiro caractere deve ser o separador do nome do caminho.

Então $HOME/Documents, ou simplesmente $HOMEnão seriam considerados diretórios absolutos? Ou essa definição implica expansão variável? E o ~personagem do shell ? Existe alguma definição confiável de diretório relativo x absoluto que eu possa encontrar em algum lugar e eu estou errado o tempo todo?

WhiteWinterWolf
fonte
7
Todos os caminhos são relativos, alguns deles são apenas relativos apenas ao diretório raiz /e aqueles que chamamos de absolutos. Assim, tudo o que começa a partir de /eu chamaria absoluto (mesmo que seja /usr/../etc) e tudo o que eu chamaria relativa ( ~/Doc, Doc, ../john/Doc, $HOME/..., ...). O ponto é que o absoluto deve funcionar independentemente do diretório de trabalho atual ou do usuário atual. O parente pode funcionar apenas em alguns casos estreitos específicos.
jimmij
6
O caminho pode se expandir para um local diferente, dependendo de quem é o usuário. Dito isto, ainda é um caminho absoluto, não relativo, na minha opinião. Embora eu não ache que as definições de caminho absoluto e relativo sejam definidas com tanta precisão. Isso não é matemática. Esta questão realmente não testa a compreensão e é inútil.
Faheem Mitha
11
@FaheemMitha: LPIC é uma certificação Linux neutra em distribuição. A certificação em si parece bom, mas isso está longe de ser o caso sobre (pelo menos alguns) de livros vendidos para se preparar para este exame como auto-estudo ...
WhiteWinterWolf
2
@jimmij: "relativo" tem um significado técnico específico no contexto dos caminhos, e usar um sentido diferente da palavra em inglês é uma prática ruim. Discordo totalmente de chamar ~/fooum caminho relativo. O que você está percebendo é a diferença entre codificação e parametrização. Veja minha resposta para mais detalhes.
Peter Cordes
11
As definições do dicionário Webster estão corretas, mas muito confusas. No entanto, isso implica que strings como ~/Documentse $HOME/Documentsnão são caminhos. Eles identificam caminhos (absolutos) após a expansão, mas não são eles mesmos. Eu acho que concorda com quantos usuários Unix / Linux usam o termo, mas sem dúvida essas strings também são chamadas de caminhos.
Reinierpost

Respostas:

41

Se o autor estava tentando descobrir você falando sobre essa cadeia literal (sem expansão do shell) como um caminho, então é um caminho relativo ( mkdir -p './~/Documents'). De outra forma:


É um caminho absoluto , porque resolvê-lo não depende do diretório de trabalho atual do processo. Caminho relativo sempre significa relativo ao diretório de trabalho do processo. Ou no caso de destinos de link simbólico, relativos ao local do link simbólico. ( gcc -> gcc-5.2vs. gcc -> /usr/bin/gcc-5.2). Isso é importante para montagens NFS e outros casos em que você pode acessar o mesmo link simbólico por diferentes caminhos absolutos. por exemplo

/net/tesla/home/peter/foo -> bar  # always works from other machines

/net/tesla/home/peter/foo -> /home/peter/bar  # references my home dir on the local machine, not tesla.

Às vezes, o Debian instala links simbólicos para ../../doc/whatever/whatever, em vez de um destino de link simbólico absoluto, então ele funciona quando o NFS é montado em outro lugar ou quando olha para um chroot sem chroot(8)entrar nele.

Todo processo Unix tem seu próprio código. O pwdcomando existe apenas para imprimi-lo.

consulte: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html para obter mais informações sobre como alterar diretórios com chamadas do sistema POSIX.


Como todo mundo já disse, ~é expandido pelo shell antes que o caminho seja usado para qualquer coisa. Usar ~/bin/myprogum script de shell fará com que funcione de maneira diferente para usuários diferentes. A diferença entre ~/bin/fooe /home/peter/bin/fooé que um deles codificou o local, enquanto o outro o parametrizou. É um erro (IMO) chamar a ~versão de caminho relativo.

Falar sobre as coisas serem "relativas a uma variável de ambiente" é apenas confuso. É uma má prática usar diferentes significados de termos em inglês que tenham significados técnicos específicos no contexto em que você os está usando.

Em um sistema quebrado, com HOME=a/relative/path, ~/fooseria expandido para um caminho relativo. Isso não seria uma configuração utilizável.

Peter Cordes
fonte
3
Obrigado por esta resposta, parece ser a mais abrangente para mim. Também tenho a impressão de que o autor erroneamente misturou a noção de caminho canônico nisso (que o autor não menciona em nenhum lugar). /opt/kde3/bin/../libpor exemplo, é erroneamente classificado como um caminho relativo: é um caminho absoluto, mas não é o caminho canônico. Como você disse, isso deixa tudo confuso, então obrigado pelo seu esclarecimento e pelas informações relacionadas ao NFS :)!
WhiteWinterWolf
11
Eu tenho que concluir que escrever um livro de preparação para o teste não é muito divertido, e que as pessoas que usam o Unix ou GNU / Linux para a computação cotidiana não são as que escrevem esses livros. Esse exemplo de chamar um caminho não canononical relativa parece realmente ruim e óbvio para mim. O man7.org/linux/man-pages/man3/realpath.3.html (e realpath(1)) faz as duas coisas: canonizar e tornar absoluto (assim como seguir links simbólicos), então, possivelmente, alguma confusão surgiu lá.
Peter Cordes
2
Ainda assim, esses são apenas conceitos cotidianos comuns para mim. Eu acho que seria estranho ter um pedaço de papel que dissesse que eu os conhecia ... Mas boa sorte fazer com que seu pedaço de papel, @WhiteWinterWolf, mostre a todas as pessoas que gostam de olhar para pedaços de papel. :)
Peter Cordes
48

Esta é essencialmente uma pergunta sobre a definição de termos. Portanto, para seus propósitos, a resposta é o que a LPIC quiser. Mas podemos chegar a algumas conclusões baseadas em fatos técnicos:

Se você passou '~/Documents'para uma chamada de sistema , procuraria um diretório nomeado exatamente ~no diretório atual (e provavelmente falhará). Portanto, pela noção de nome de caminho usada pelo kernel , esse é um caminho relativo - mas não é isso que queremos dizer.

~é uma sintaxe implementada pelo shell (e outros programas que o imitam por conveniência) que o expande para um nome de caminho real. Para ilustrar, ~/Documentsé aproximadamente a mesma coisa que $HOME/Documents(novamente, sintaxe do shell). Como $HOMEdeve ser um caminho absoluto, o valor de $HOME/Documents também é um caminho absoluto. Mas o texto $HOME/Documentsou ~/Documentsprecisa ser expandido pelo shell para se tornar o caminho que queremos dizer.

Assim, se eu quisesse ser preciso e consistente, diria que ~/Documentsé um fragmento de shell-script que se expande para um caminho absoluto.

Kevin Reid
fonte
Obviamente, o kernel não tem idéia do que $HOMEsignifica, assim como não tem idéia do que ~significa. Contudo, acho a afirmação de que a expansão é feita pelo shell como duvidosa; a maioria dos aplicativos suporta isso, que aponta para a biblioteca C e não para o shell. A expansão da variável de ambiente, no entanto, é um recurso do shell; você pode abrir ~/somefile.odtno LibreOffice, mas não $HOME/somefile.odt, mesmo que o LibreOffice tenha sido iniciado a partir de um shell no qual $ HOME esteja definido corretamente.
um CVn
5
Você pode encontrar tudo isso duvidoso que você quer, mas está documentado e deve ser fácil para confirmar ou desmentir em C.
Useless
6
Outros programas implementam ~sintaxe na imitação do shell, porque é um atalho útil. Na verdade, eu não sei se existe uma função de biblioteca que faz a expansão, mas é definitivamente algo que é feito separadamente do uso do nome do caminho.
Kevin Reid
2
globe wordexpfaça expansão til entre outras coisas.
o11c 9/08/2015
2
@ MichaelKjörling: Alguns programas implementam ~expansão; a maioria não. Por exemplo, se você digitar ls -l ~, o lsprograma nunca verá o ~caractere; é expandido pelo shell antes de lsser chamado. Se você realmente passar um ~para ls, ele não o tratará especialmente; try ls -l '~'' (que tentará listar um arquivo chamado literalmente ~).
9788 Keith Thompson #
16

Se você $HOMEé /home/white/, ~/Documents(o mesmo que $HOME/Documents) é expandido pelo shell (veja aqui uma explicação) para /home/white/Documents, que é um caminho absoluto .

Um caminho relativo é aquele que não inicia com /(após a expansão do shell), como ../Documentsoufoo/bar

Alguns escudos antigos não se expandam ~(a forma como bash, tcsh, zsh, etc. ... fazer); eles veriam ~/Documentscomo um caminho relativo começando com ~; mas você normalmente não tem o nome do diretório como ~(mas pode criar um com o mkdir '~'qual eu não recomendo).

Basile Starynkevitch
fonte
você deve mencionar que conchas dont expandir~
Edward Torvalds
3

Um caminho absoluto começa em /(o que se refere é fixo), um caminho relativo começa no diretório atual (e, portanto, o que se refere a alterações à medida que o diretório atual é alterado). A maioria dos shells usa ~no início como uma abreviação para o caminho absoluto para o diretório inicial do usuário atual, ou seja, ~/Documentsé o diretório Documentsna página inicial do usuário atual, independentemente do diretório atual. Portanto, é um caminho absoluto.

vonbrand
fonte
1

O caminho pode se expandir para um local diferente, dependendo de quem é o usuário. Dito isto, ainda é um caminho absoluto, não relativo, na minha opinião. No entanto, não acho que as definições de caminho absoluto e relativo sejam definidas com tanta precisão. Isso não é matemática. Esta pergunta realmente não prova a compreensão, na minha opinião, e é inútil.

Faheem Mitha
fonte
A definição é muito mais que opinião. Wikipedia tem uma facada nele para o caso geral, não apenas Unix: en.wikipedia.org/wiki/...
Peter Cordes
1

O uso do ~ / no início torna o caminho absoluto, pois (por qualquer definição) a capacidade de encontrar documentos não depende de onde você está atualmente. No entanto, a expansão é feita pelo shell, não pelo kernel; portanto, se você estiver usando um shell que não reconheça essa sintaxe (como / bin / sh, o shell Bourne original, e não o alias do bash), você ficará sem sorte.

Curiosamente, se você usar ~ root / em vez de ~ /, a otimização da leitura de $ HOME normalmente não se aplica e sempre será resolvida como absoluta se / etc / passwd estiver correto.

jrrk
fonte
-1

O livro parece considerar que um caminho absoluto é qualquer caminho que comece com a /e um caminho relativo é qualquer outra coisa.

Você pode visualizar ..e $HOMEcomo tipos semelhantes de tokens. Ambos precisam ser substituídos, por um componente do caminho, antes que o caminho resolva para um caminho absoluto.

jl6
fonte
3
Como é ..algo assim $HOME? ..pode estar no início de um caminho passado diretamente para uma chamada do sistema, sem necessidade de expansão do shell. Esse caminho não é absoluto; ainda é relativo ao local cwd ou link simbólico do processo. A menos que o autor esteja tentando descobrir você falando sobre essa string literal (sem expansão do shell) como um caminho. Acho que você está tentando inventar desculpas para o livro, mas estou mais inclinado a dizer que está errado e não deixar as coisas ficarem confusas.
Peter Cordes