Regras de sintaxe de caminho

9

Estou escrevendo uma biblioteca para manipular cadeias de caminho Unix. Sendo esse o caso, eu preciso entender alguns cantos obscuros da sintaxe com a qual a maioria das pessoas não se preocuparia.

Por exemplo, da melhor maneira possível, parece que foo/bar e foo//bar apontam para o mesmo lugar.

Além disso, ~ geralmente representa o diretório pessoal do usuário, mas e se ele aparecer no meio de um caminho? O que acontece então?

Estas e várias dúzias de outras perguntas obscuras precisam ser respondidas se eu for escrever código que lide com todos os casos possíveis corretamente. Alguém sabe de uma referência definitiva que explique as regras de sintaxe exact para essas coisas?

(Infelizmente, procurar termos como "Unix path syntax" apenas mostra um milhão de páginas discutindo a variável $PATH ... Heck, estou até mesmo lutando para encontrar tags adequadas para essa pergunta!)

    
por MathematicalOrchid 19.04.2014 / 11:01

2 respostas

12

Existem três tipos de caminhos:

  • caminhos relativos como foo , foo/bar , ../a , . . Eles não começam com / e são relativos ao diretório atual do processo que faz uma chamada do sistema com esse caminho.
  • caminhos absolutos, como / , /foo/bar ou ///x . Eles começam com 1, ou 3 ou mais / , não são relativos, são pesquisados a partir do diretório raiz / .
  • POSIX permite que //foo seja tratado especialmente, mas não especifica como. Alguns sistemas usam isso para casos especiais, como arquivos de rede . Tem que ser exatamente 2 barras.

Diferentemente do início, as sequências de barras agem como uma.

~ é especial apenas para o shell , ele é expandido pelo shell, não é especial para o sistema em todos. Como ele é expandido depende do shell. Shells fazem outras formas de expansão como globbing ( *.txt ) ou expansão variável /$foo/$bar ou outras. No que diz respeito ao sistema ~foo é apenas um caminho relativo como _foo ou foo .

Coisas a ter em conta:

  • foo/ não é o mesmo que foo . Ele está mais próximo de foo/. than foo (especialmente se foo for um symlink) para a maioria das chamadas de sistema na maioria dos sistemas ( foo// é o mesmo que foo/ ).
  • a/b/../c não é necessariamente igual a a/c (por exemplo, se a/b for um symlink). Melhor não é tratar .. especialmente.
  • geralmente é seguro considerar a/././././b o mesmo que a/b .
por 19.04.2014 / 11:13
3

For example, as best as I can tell, it seems that foo/bar and foo//bar both point to the same place.

Sim. Isso é comum porque o software às vezes concatena um caminho assumindo que a primeira parte não foi terminada com uma barra invertida, de modo que um é acionado para ter certeza (significando que pode acabar sendo dois ou mais). foo///bar e foo/////bar também apontam para o mesmo local que foo/bar . Uma boa função para uma biblioteca de manipulação de caminhos seria uma que reduzisse qualquer número de barras sequenciais a uma (exceto no começo de um caminho, onde ele poderia ser usado de uma maneira de URL, ou, como Stephane aponta, para qualquer propósito especial não especificado).

Also, ~ usually stands for the user's home directory

Essa transformação é feita por meio do shell e da expansão do til , que somente funciona se for o primeiro caractere no caminho. Se você precisa ou não lidar com isso depende do contexto. Se a biblioteca é para ser usada com programas normais que recebem, por exemplo, argumentos de linha de comando contendo um caminho, a expansão de til já é feita quando eles vêem o caminho. A única situação que vejo é uma preocupação se você estiver processando caminhos diretamente de um arquivo de texto.

Além disso, ~ é um caractere legal em um caminho * nix e não deve ser alterado para mais nada. Como por este , os únicos caracteres que não são legais em um nome de arquivo unix são / (porque é o separador de caminho) e "null" (também conhecido como byte zero) porque eles são ilegais no texto em geral.

    
por 19.04.2014 / 11:10