Est-ce une bonne pratique d'exiger une barre oblique de fin dans les noms de répertoire?

9

Je veux demander à l'utilisateur de mon script bash de passer un chemin de répertoire en argument. Lequel des énoncés suivants est une bonne pratique de programmation?

  • Exiger que l'utilisateur saisisse une barre oblique / (barre oblique)
  • Exiger qu'un utilisateur n'entre pas de fin / (barre oblique)
Rohit Agarwal
la source
3
Notez que rsyncse comporte différemment d'une manière très importante en fonction de la présence de fin /, et donc dans certains cas, vous voudriez normaliser pour la cohérence, et dans d'autres vous voudriez passer proprement pour implémenter ce que l'utilisateur a dit (s'ils savait qu'ils parlaient rsync).
sh1
Un autre qui m'a surpris est récemment que ls -l dirse comporte différemment à s'est un lien symbolique vers un répertoire. ls -l dir/dir
Flimm

Réponses:

27

La meilleure pratique consiste à ne supposer ni l'un ni l'autre.

Si vous avez accès à des utilitaires / classes de générateur de chemin, utilisez-les, sinon écrivez votre code pour accepter l'un ou l'autre format et agissez en conséquence.

Rien de plus ennuyeux pour l'utilisateur que de devoir se souvenir d'ajouter ou non une barre oblique de fin.

ChrisF
la source
6
Corollaire: toujours analyser les chemins avec les outils de ligne de commande appropriés - dirname, basenameet readlink. Un problème très courant consiste à ${path##*/}remplacer basename, mais si le chemin se termine par une barre oblique qui renvoie une chaîne vide au lieu du dernier élément de chemin.
l0b0
1
+1 pour l'utilisation des classes utilitaires. Je ne peux pas dire combien de fois j'ai vu des développeurs réinventer la roue quand il s'agit d'assembler des chemins, alors que la plupart des frameworks peuvent le faire facilement de nos jours.
RationalGeek
1
De plus, je suis très ennuyé lorsqu'une application me demande de le faire d'une manière spécifique. Et parfois, l'utilisateur ne peut pas contrôler comment écrire ce chemin: Parfois, il l'écrit, alors oui, il choisit d'écrire avec ou sans barre oblique de fin, mais dans les cas où l'utilisateur se termine automatiquement à l'aide de TAB, de nombreux shells mettent la barre oblique de fin, vous demanderiez donc à l'utilisateur de le supprimer? Et encore plus ennuyeux, c'est lorsqu'une application se comporte différemment si vous mettez la barre oblique de fin dans un répertoire passé en argument ( rsyncje vous regarde)
Carlos Campderrós
J'ai récemment eu besoin de vérifier une barre oblique de fin à partir de l'entrée utilisateur pour l'utiliser avec rsync (car il est sensible à ces choses). Comme l'a noté @ChrisF, il est préférable de ne supposer ni l'un ni l'autre. J'ai proposé ce qui suit comme une façon gracieuse de supposer ni l'un ni l'autre: ${STR}$(printf \\$(printf '%03o' $(($(printf '%d' "'${STR:(-1)}")==47?0:47))))je l'ai également documenté dans un sens pour plus de clarté: ajouter ou supprimer une barre oblique de fin dans bash
John Mark Mitchell
10

Étant donné que bash ignore plusieurs barres obliques, vous pouvez supposer en toute sécurité que l'utilisateur n'a pas entré de barre oblique de fin dans le chemin d'accès et ajouter une barre oblique vous-même.

cat /etc/hosts

c'est pareil

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

Votre script pourrait donc ressembler à ça:

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

et vous n'avez pas à vous soucier de savoir si l'utilisateur entre ou non dans le chemin.

user281377
la source
5
Nit: Ce n'est pas un bashcomportement, le noyau le fait.
Blrfl
7

Le regretté Jon Postel a donné d'excellents conseils dans la section 3.2 de la RFC 760 qui s'applique ici:

En général, une implémentation doit être conservatrice dans son comportement d'envoi et libérale dans son comportement de réception. Autrement dit, il doit être prudent d'envoyer des datagrammes bien formés, mais doit accepter tout datagramme qu'il peut interpréter (par exemple, ne pas s'opposer aux erreurs techniques dont le sens est toujours clair).

Blrfl
la source
3

Conceptuellement, la barre oblique ne fait pas partie du nom. La barre oblique n'est qu'un délimiteur entre les noms. Mon répertoire personnel est / home / stefan et non / home / stefan /.

Si vous ne vous attendez pas à une barre oblique finale, vous n'échouerez pas s'il y en a une, comme ammoQ l'a déjà noté. Mais vous pouvez facilement coller des noms et des variables, car vous n'avez pas à citer la barre oblique:

a="/home"
b="stefan"

dir=$a/$b
Utilisateur inconnu
la source
0

Exiger que le répertoire ne contienne pas de barre oblique de fin serait extrêmement ennuyeux pour une utilisation interactive sur la console: la complétion automatique avec TAB ajoute automatiquement une barre oblique de fin pour les répertoires.

Vous devez donc certainement autoriser que les répertoires soient spécifiés avec une barre oblique de fin.

oberlies
la source