É uma boa prática exigir uma barra à direita nos nomes de diretório?

9

Quero pedir ao usuário do meu script bash para passar um caminho de diretório como argumento. Qual das alternativas a seguir é uma boa prática de programação?

  • Exigir que o usuário insira uma barra final / (barra)
  • Exigir que um usuário não insira uma barra final / (barra)
Rohit Agarwal
fonte
3
Observe que rsyncse comporta de maneira diferente de uma maneira muito importante, dependendo da presença de rastreamento /, e, em alguns casos, você deseja normalizar a consistência e, em outros, deseja passar de maneira limpa para implementar o que o usuário disse (se eles sabia que eles estavam conversando rsync).
sh1 03/07
Outro que me surpreendeu recentemente é que ls -l dirse comporta de maneira diferente ls -l dir/se diré um link simbólico para um diretório.
Flimm

Respostas:

27

A melhor prática é assumir nenhum dos dois.

Se você tiver acesso aos utilitários / classes do construtor de caminhos, use-os; caso contrário, escreva seu código para aceitar qualquer formato e agir de acordo.

Nada é mais irritante para o usuário do que ter que lembrar se deve adicionar uma barra final ou não.

ChrisF
fonte
6
Corolário: sempre analise os caminhos com as ferramentas de linha de comando adequadas - dirname, basenamee readlink. Um problema muito comum é usar ${path##*/}como substituto basename, mas se o caminho terminar com uma barra que retorna uma cadeia vazia em vez do último elemento do caminho.
L0b0 17/06/11
11
+1 para usar classes de utilidade. Não sei dizer quantas vezes vi desenvolvedores reinventarem a roda quando se trata de montar caminhos, quando a maioria das estruturas pode fazê-lo facilmente hoje em dia.
RationalGeek
11
Além disso, fico muito chateado quando algum aplicativo exige que eu faça isso de uma maneira específica. E, às vezes, o usuário não pode controlar como escrever esse caminho: às vezes o escreve, então sim, eles escolhem escrever com ou sem barra final, mas nos casos em que o usuário se autocompleta usando TAB, muitas conchas colocam a barra final, então você exigiria que o usuário a excluísse? E ainda mais irritante é quando um aplicativo se comporta de forma diferente se você colocar a barra final em um diretório passado como um argumento ( rsyncque eu estou olhando para você)
Carlos Campderrós
Recentemente, precisei verificar uma barra à direita da entrada do usuário para uso com o rsync (pois é sensível a essas coisas). Como o @ChrisF observou, é uma prática recomendada não assumir nenhum dos dois. Eu vim com o seguinte como uma forma graciosa de assumir nem: ${STR}$(printf \\$(printf '%03o' $(($(printf '%d' "'${STR:(-1)}")==47?0:47))))Eu também documentou-lo em uma essência para maior clareza: adicionar ou remover barra invertida em bash
John Mark Mitchell
10

Como o bash ignora várias barras, você pode assumir com segurança que o usuário não inseriu uma barra no caminho e adicionar uma barra você mesmo.

cat /etc/hosts

é o mesmo que

cat /////etc//////////hosts

Portanto, seu script pode ficar assim:

echo -n "enter path: "
read path
if [ -f $path/myfile ]
then
  echo "found myfile!"
else
  echo "nope"
fi

e você não precisa se preocupar se o usuário entra ou não no caminho.

user281377
fonte
5
Nit: Isso não é bashcomportamento, o kernel faz.
Blrfl
7

O falecido Jon Postel teve ótimos conselhos na seção 3.2 da RFC 760 que se aplica aqui:

Em geral, uma implementação deve ser conservadora no comportamento de envio e liberal no comportamento de recebimento. Ou seja, deve-se ter o cuidado de enviar datagramas bem formados, mas deve aceitar qualquer datagrama que possa interpretar (por exemplo, não se oponha a erros técnicos em que o significado ainda esteja claro).

Blrfl
fonte
3

Conceitualmente, a barra não faz parte do nome. A barra é apenas um delimitador entre nomes. Meu diretório home é / home / stefan e não / home / stefan /.

Se você não espera uma barra final, não falhará se houver uma, como a muniçãoQ já observou. Mas você pode facilmente colar nomes e vars, porque não precisa citar a barra:

a="/home"
b="stefan"

dir=$a/$b
Usuário desconhecido
fonte
0

Exigir que o diretório não deva ter uma barra final seria extremamente irritante para uso interativo no console: o preenchimento automático com o TAB adiciona automaticamente uma barra final aos diretórios.

Portanto, você certamente precisa permitir que os diretórios sejam especificados com barra final.

Oberlies
fonte