Regras de sintaxe do caminho

10

Estou escrevendo uma biblioteca para manipulação de strings de caminho Unix. Sendo esse o caso, preciso entender alguns cantos obscuros da sintaxe com os quais a maioria das pessoas não se preocuparia.

Por exemplo, o melhor que eu posso dizer, parece que foo/bare foo//barambos apontam para o mesmo lugar.

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

Essas e várias dezenas de outras perguntas obscuras precisam ser respondidas se eu escrever um 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 exata para este material?

(Infelizmente, pesquisar termos como "Sintaxe do caminho Unix" aparece um milhão de páginas discutindo a $PATHvariável ... Caramba, estou até lutando para encontrar tags adequadas para essa pergunta!)

MathematicsOrchid
fonte
A expansão ok ~ til e -filename estão subjacentes aos recursos definidos pelo POSIX de qualquer ambiente Unix. Algumas dicas: um nome de arquivo pode ser qualquer coisa, exceto \ 0 ou /. ////// e / são a mesma coisa. $ PWD é tratado no kernel e pode ser lido para qualquer processo (Linux) em / proc. /./ pode ocorrer apenas na raiz de um caminho. Em $ PATH ::::: e: são a mesma coisa. / dev / null / dev / tty e / tmp são caminhos garantidos pelo POSIX para todos os sistemas conformes.
precisa saber é o seguinte
1
A maioria das suas perguntas (mas não a parte sobre ~) é abordada em Como o linux lida com vários separadores de caminho (/ home //// nome_do_usuário /// arquivo) . A coisa mais próxima de uma referência normativa seria a especificação POSIX ou Single Unix - não é uma leitura fácil.
Gilles 'SO- stop being evil'

Respostas:

13

Existem três tipos de caminhos:

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

Além do início, as seqüências de barras agem como uma.

~é especial apenas para o shell , é expandido pelo shell, não é especial para o sistema. Como é expandido depende do shell. Os reservatórios realizam outras formas de expansão, como globbing ( *.txt), expansão variável /$foo/$barou outros. No que diz respeito ao sistema, ~fooé apenas um caminho relativo como _fooou foo.

Coisas a ter em mente:

  • foo/não é o mesmo que foo. É mais próximo do foo/.que foo(especialmente se foohouver um link simbólico) para a maioria das chamadas de sistema na maioria dos sistemas ( foo//é o mesmo que se foo/fosse).
  • a/b/../cnão é necessariamente o mesmo que a/c(por exemplo, se a/bfor um link simbólico). Melhor não é tratar ..especialmente.
  • geralmente é seguro considerar a/././././bo mesmo como a/bse.
Stéphane Chazelas
fonte
Então, em resumo, se eu não me importo com caminho manipulação shell (que é vasto e complicado), eu só precisa se preocupar com /, .e ..(?)
MathematicalOrchid
Um exemplo de //foomanipulação está no Cygwin, onde é usado para caminhos UNC . Ou seja, //server/share/dir/file.txté um caminho legal que aponta para fora do sistema por padrão. Cygwin volta a olhar para o sistema local, se não conseguir encontrá-lo server.
Warren Young
3

Por exemplo, o melhor que posso dizer, parece que foo / bar e foo // bar apontam para o mesmo lugar.

Sim. Isso é comum porque o software às vezes concatena um caminho, assumindo que a primeira parte não foi finalizada com uma barra, então uma é lançada para ter certeza (o que significa que pode haver dois ou mais). foo///bare foo/////bartambém aponte para o mesmo local que foo/bar. Uma boa função para uma biblioteca de manipulação de caminho seria aquela que reduz qualquer número de barras sequenciais para uma (exceto no início de um caminho, onde pode ser usada de maneira isenta de URL ou, como Stephane indica, para qualquer finalidade especial não especificada).

Além disso, ~ geralmente significa o diretório inicial do usuário

Essa transformação é feita via exapansão shell e til , que só 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 usado com programas normais que recebem, por exemplo, argumentos de linha de comando contendo um caminho, tilde expansão é feito quando vêem o caminho. A única situação que vejo como preocupante é se você está 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. De acordo com isso , os únicos caracteres que não são válidos em um nome de arquivo unix são /(porque é o separador de caminho) e "nulo" (também conhecido como zero byte), porque geralmente são ilegais no texto.

Cachinhos Dourados
fonte
+1 para a explicação da expansão do til; Eu não tinha ideia de que você poderia consultar outros usuários com ele!
MathematicalOrchid
2
Como Stephane diz, você não pode recolher cegamente todas as barras repetidas para a frente. Várias barras no início do caminho devem ser tratadas com cuidado.
Warren Young
@WarrenYoung Editado para deixar isso claro. PS. Frente??! O_O
goldilocks
Melhor, embora eu não diria que isso tem algo a ver com URLs. O UNC remonta ao final dos anos 80, enquanto os URLs não apareceram até anos depois.
Warren Young
@WarrenYoung Fair o suficiente, embora pareça que os UNC são específicos para plataformas de MS , //tecnicamente também não é isso. Tanto o URLS quanto a especificação POSIX livremente ambígua, de acordo com SC mais recente, // podem ter sido derivados disso; nesse caso, "URL-ish" parece um rótulo adequado para a convenção (mesmo que os UNCs sejam mais antigos e até mesmo a aparência) não é intencional). Eu nunca diria que "eles são URLS", apenas isso //ou \\ serve a um propósito "URL-ish".
GOLDILOCKS