Uma variável de caminho de diretório deve terminar com uma barra final?


88

Ao definir um caminho para um diretório como uma variável ou constante, ele deve terminar com uma barra final? Qual é a convenção?

pwdno Unix mostra seu diretório atual sem uma barra final, enquanto a guia completa cd /var/www/apps/inclui a barra final, o que me deixou inseguro.

Respostas:


24

Não incluo a barra final quando, por exemplo, defino um diretório para armazenar arquivos. Isso é porque vou usá-lo como

$store_file = "$store_path/$file_id";

Sempre adicionarei uma barra final antes de usar uma variável que deveria conter um caminho de diretório. Acho que é melhor sempre adicionar um do que se perguntar se a barra final está incluída.


29
Não ter uma barra final significa que não está claro se o caminho em $ store_path é um arquivo ou diretório. "/ tmp / store_data" é um arquivo ou diretório?
Darwin

4
Ao usar algo como a função realpath () do PHP , ele não imprimirá a barra final. Seu sistema e ferramentas podem ditar sua convenção.
jmbertucci

10
Ter várias barras em qualquer lugar geralmente será interpretado como uma única barra. Então você poderia até ter algo parecido '///' + $root + '//' + $file + '/'e não faria diferença. Embora ter a barra final seja uma boa maneira de discernir se o caminho é ou não um arquivo ou diretório, seria melhor anexar a caminhos como '/' + $rootdo que $root + '/'porque você não pode ter certeza de que o caminho que está sendo anexado tem uma barra final , mas você pode estar relativamente certo de que várias barras serão interpretadas como uma única barra na maioria dos ambientes.
Xtrinity

3
@MatthewSlyman, Meu ponto é que todo mundo espera que este /tmp/store_data/seja um diretório, enquanto não está claro qual é o mesmo caminho sem uma barra traling/tmp/store_data
Darwin

6
O problema com isso é: se uma variável não existir, ela será o mesmo que vazia e a rm -rf $foo/$barpode terminar emrm -rf /
12431234123412341234123

102

Eu escolho a barra final porque:

  1. "Se terminar com uma barra, é um diretório. Se não, é um arquivo." é uma convenção fácil de lembrar.

  2. Pelo menos nos sistemas operacionais que costumo usar, dobrar a barra não causa problemas, enquanto omitir a barra causa problemas maiores. Portanto, é mais seguro colocar a barra na variável e usar "$ path / $ file" ao fazer uso dela.


9
Um caminho de diretório só é distinguível de um caminho de arquivo se o caminho de diretório tiver uma barra final.
Darwin

4
Múltiplas barras equivalem a uma barra, a menos que o caminho comece com barra dupla. Consulte unix.stackexchange.com/questions/1910/…
jdh8

4
Além disso, adicionar uma barra no final da variável permite "$ path $ file" em vez de "$ path / $ file", o que permite $ path vazio - significando o diretório de trabalho atual. Mas nunca use barra invertida em vez de barra.
fantastory

Os descritores de arquivo também são úteis
Francesco Gualazzi

@ jdh8 Mesmo que o caminho comece com barras duplas, ele ainda deve ser equivalente a uma barra. Embora isso possa mudar de implementação para implementação. Os padrões unix afirmam que, A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash.na maior parte, foi observado que barras duplas geralmente são interpretadas como uma única barra em implementações comuns.
Xtrinity de

14

Eu sei que isso tem 10 anos, mas eu queria jogar meus muito teimosos $ 0,02.

Não. Não. Absolutamente não.

Estamos falando de um sistema Unix. Em referência ao próprio diretório, é um nó como qualquer outro. Ao se referir ao diretório, ele não deve nunca ter uma barra unescaped em seu nome (ref: dirname, pwd, ~, echo $HOME, echo $PATH, a saída ls, et al).

Quando se refere a conteúdo de um diretório, então você precisa de uma barra. Quer dizer, ls /home/karl/é mais adequado do que ls /home/karl(FTR, quase sempre faço o último porque ... bom, preguiçoso).

Ao utilizar uma variável que contém um diretório para criar o caminho completo para um arquivo, você sempre esperaria incluir a barra (i., E cp ${HOME}/test ${OTHER_DIR}/:).

Espera- se que um diretório não termine em uma barra. Qualquer expectativa de que um diretório termine em uma barra está errada. Assim, adicionar uma barra ao final *_DIRdo valor de uma variável estaria subvertendo as expectativas.

Quanto ao preenchimento da guia, a expectativa aqui é que você vá para esse diretório. Portanto, a ajuda fornecida pelo preenchimento da guia é para levá-lo a esse diretório para que você possa fazer a próxima escolha com base em seu conteúdo.

(referência de comentários: equívocos de caminho de arquivo , da Talk:Path_(computing)página da Wikipedia . Obrigado, john cj )

É importante notar que só porque é errado, não significa que ferramentas / pacotes / bibliotecas nunca o façam. É uma ocorrência muito comum que essas coisas adicionem uma barra final quando nenhuma deveria existir. Portanto, como Bevan e Paul F sugeriram, ao usar ferramentas de terceiros, é melhor remover quaisquer barras finais que possam existir nos nomes de diretório.

Unix Inodes

O inode (nó de índice) é uma estrutura de dados em um sistema de arquivos no estilo Unix que descreve um objeto do sistema de arquivos, como um arquivo ou diretório.

- https://en.wikipedia.org/wiki/Inode

Padrão de hierarquia do sistema de arquivos

O padrão para o sistema de arquivos Unix (o Filesystem Hierarchy Standard, também conhecido como FHS) mostra claramente que os diretórios não são considerados como tendo uma barra final, mas sim o conteúdo do diretório começa com uma barra (a única exceção a isso é /porque não iremos nos referir a a raiz do sistema de arquivos usando uma string vazia ... e nunca se deve criar arquivos lá de qualquer maneira.)

- http://www.pathname.com/fhs/pub/fhs-2.3.html

- https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard


Excelente resposta. Costumava usar essa abordagem, mas nunca fui totalmente completo quanto ao meu raciocínio. Esta é a única resposta que acerta.
wardw

4
É a raiz /que quebra o padrão. E se você fosse começar seu raciocínio a partir daqui (recursivamente), você pode então chegar às contradições que podem estar no cerne das práticas divergentes (como evidenciado pelas respostas aqui). Mas, uma vez que você aceita isso como exceção, todo o resto se alinha.
wardw

Eu vejo. Demorou um pouco para brincar com dirname. Se você pretende armazenar explicitamente um diretório em um caminho, termine o caminho com um “/.”, Onde o ponto representa o diretório atual.
TamusJRoyce

2
@wardw você poderia pensar no diretório raiz como sendo nomeado uma string vazia, enquanto "/" é uma string vazia seguida por uma barra e significa "o conteúdo do diretório raiz".
bobpaul de

1
Esta resposta deve ser votada mais a favor. Veja também a seção de equívocos de caminho de arquivo no Wiki.
john cj

9

Sim, deveria, como:

Pathname + filename = localização do arquivo totalmente qualificado.

ASSIM, a barra entre o último diretório e o nome do arquivo precisa estar no final do nome do caminho ou no início do nome do arquivo. Prefixar nomes de arquivos com um / significa que você precisa levar isso em consideração se quiser apenas abrir um arquivo (ou seja, se você assumir que um nome de arquivo não qualificado está no diretório de trabalho atual).


5
.. e deixar de levar isso em consideração significa que você está possivelmente inadvertidamente brincando com /, e dessa forma a loucura reside
JustJeff

5

Sempre que armazeno caminhos de diretório ou os retorno de APIs, tento manter a convenção de manter uma barra final. Isso evita toda a ambigüidade 'é um arquivo ou um diretório'.

Adendo :
não pretende ser um substituto para o uso de métodos que podem tolerar uma barra final ou sua ausência. Mesmo usando essa convenção, ainda uso Path.Combine(...)métodos semelhantes.


python:os.path.join(dir, subdir_or_file)
IceArdor

5

Talvez você deva pensar sobre o que sua decisão significaria para os arquivos. Se você não incluir a barra final no final de um nome de diretório, você terá que adicioná-la ao início do nome do arquivo .

Agora, se por algum motivo, o caminho que leva ao arquivo está faltando quando você concatenar strings, você acaba com algo como /filenameque não é apenas um arquivo, mas um caminho absoluto do diretório raiz (onde quer que esteja nesse contexto) .

É por isso que termino meus caminhos com uma barra e mantenho os arquivos como arquivos.


1
A alternativa aqui é expressar seu nome de arquivo como ./filename. Mas, em geral, deve ser responsabilidade do código concatenar os caminhos para fazê-lo corretamente - e não fazer suposições de qualquer maneira.
wardw

4

Eu sei que este é um tópico antigo, mas pensei em compartilhar o que faço. Se possível, eu normalmente permitiria ambos e faria algo assim (se fosse PHP):

$fullPath = rtrim($directory, '/') . '/filename.txt');

Dessa forma, se o diretório for definido em um arquivo de configuração, não importa se a próxima pessoa a alterá-lo inclui a barra final ou não.


4

No php, como a função dirname (__ FILE __) retorna o nome do diretório sem uma barra no final. Tenho tendência a seguir essa convenção.

Caso contrário, usar uma barra no final de um nome de diretório entrará em conflito com a maneira como dirname (..) funciona e então você terá que lidar com os dois casos, já que não sabe se o nome do diretório veio de um dirname (.. ) função ou um conteúdo definido com uma barra final.

Resumindo: não use uma barra final, pois dirname (..) não usa.

// PHP Example
dirname(__FILE__); // returns c:\my\directory without a trailing slash, so stick to it!

Para outros idiomas, verifique a função que extrai o nome do caminho e veja se está usando uma barra final ou não, e siga a convenção do idioma.


2
Uma exceção: dirname ('/ test') = '/' - ao invés de retornar uma string vazia, dirname retorna uma única barra neste caso! Veja as notas aqui .
Matthew Slyman de


2

Sim, existem muitos sistemas de arquivos que suportam arquivos sem extensões, portanto, sempre adicione a barra final para evitar problemas.


1

Nunca vi uma convenção firme de qualquer maneira.

Porém, com certeza, seja o que for que você decidir, outra pessoa terá 100% de certeza que deveria ser o contrário. Portanto, a melhor ideia é tolerar que as coisas sejam definidas de qualquer maneira.

No mundo .NET, Path.Combine () oferece uma maneira de lidar com isso - existem equivalentes em outros ambientes, de arquivos cmd em diante.


1

Acho que este é um daqueles raros casos em que a resposta correta teórica e prática é diferente.

Parece que a resposta de @Karl Wilbur com certeza está correta em um sentido teórico, já que você deve ser capaz de distinguir uma referência ao próprio nó do diretório do conteúdo do diretório.

Mas, na prática, argumentarei que a resposta correta é o oposto:

  • O motivo mais importante é que você pode dizer com certeza que o caminho /home/FSObjectX/é uma pasta, embora /home/FSObjectXseja ambíguo. Ninguém pode dizer se este é um arquivo ou uma pasta.
    As especificações devem ser precisas e inequívocas sempre que possível.

  • Na grande maioria dos casos, você sempre fará referência ao conteúdo de uma pasta, não ao nó dir em si.
    Nos raros casos em que você realmente o faz, isso pode ser facilmente tratado no código removendo qualquer separador de dir à direita opcional.

  • Usar separadores dir duplos não causará nenhum dano, embora faltar um certamente fará.
    Em teoria, um argumento ruim, já que você não deveria codificar por "acaso", mas na prática, os erros acontecem, e talvez o uso de dir-sep final possa resultar em alguns erros de tempo de execução a menos no usuário final.

Lendo este tópico interessante, não encontrei nenhuma desvantagem de usar trailing dir-sep, apenas que está errado em um sentido teórico. Ou eu perdi alguma coisa?


na prática, você descobrirá que a expectativa adequada é não conter uma barra final. Basta olhar para todas as ferramentas que você usa e que foram escritas por desenvolvedores competentes.
Karl Wilbur
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.