Pourquoi mkdir n'a-t-il pas le drapeau -p défini par défaut pour permettre la création de répertoires imbriqués?

11

Je ne vois aucune raison pour laquelle le -pdrapeau mkdirne devrait pas être défini par défaut.

  -p, --parents     no error if existing, make parent directories as needed

C'est une commande non destructive d'après ce que je peux voir. Ai-je oublié quelque chose d'important sur la façon dont cela fonctionne?

Deuxièmement, existe-t-il un moyen simple d'obtenir ce comportement par défaut mkdir?

Treffynnon
la source
2
mettre dans votre .bashrc: alias mkdir="mkdir -p".
Kevin
Après toute la discussion, j'ai décidé d'aller avec un alias demkdp
Treffynnon

Réponses:

6

Il s'agit d'une fonctionnalité facultative, qui n'est pas toujours souhaitée - en particulier dans les scripts. Envisagez les inconvénients suivants en cas de scripts:

  • Le fait que le répertoire existe déjà n'est pas signalé: si un script est censé mettre des fichiers dans un répertoire nouvellement créé et que ce répertoire existe déjà et contient des fichiers, le script peut faire beaucoup de dégâts. (Il sera difficile de filtrer plus tard les fichiers qui y ont été placés par le script.)
  • À l'inverse de ce qui précède, certains scripts (ou une partie de ceux-ci) peuvent dépendre d'une structure de répertoires créée précédemment (éventuellement par un autre package / script). Par exemple, un script d'installation de package peut avoir besoin de placer des bibliothèques dans un sous-répertoire /usr/local/lib/GreatSoftware/ImportantPartOfIt, mais les bibliothèques dépendent de / link pour se trouver sous /usr/local/lib/GreatSoftware. Si cela manque, le script ne doit pas continuer.

Le comportement générique de la mkdirrend facile et naturel, car de telles situations sont signalées et peuvent être détectées immédiatement.


Vous pouvez lui créer un alias si vous souhaitez toujours l'utiliser mkdir -pdans vos shells:

alias mkdir='mkdir -p'

(Cela devrait aller dans votre .bashrcconfiguration ou dans la configuration que votre shell utilise.)

rozcietrzewiacz
la source
1
Je ne suggérerais pas d'alias une commande standard pour qu'elle se comporte de manière non standard. Cela rendrait les scripts non portables et pourrait dérouter les lecteurs. Créer un nouvel alias ou une nouvelle fonction, comme ce alias mkdp="mkdir -p"serait plus conseillé.
jlliagre
2
@jlliagre Non, cela n'affecterait pas les scripts. Les alias définis localement dans .bashrcn'affectent pas (normalement) leurs environnements.
rozcietrzewiacz
En effet, mais vous avez manqué mon point. Aliaser une commande standard pour changer son comportement, même pour votre propre usage, n'est pas une pratique recommandée. Le pire exemple étant l'omniprésent alias rm='rm -i'.
jlliagre
1
@jlliagre Non recommandé par qui? ;) Mais oui, je suis d'accord, je préfère moi-même utiliser un pseudonyme différent - mais pour des raisons pratiques et non idéologiques. Je ne pense pas non plus que l' rm -ialias soit toujours mauvais - bien que cela puisse conduire à de mauvaises habitudes. Certes, tous les alias de commande ne sont pas également bons / mauvais - considérez ls="ls --color=auto"ou ssh="TERM=xterm ssh"par exemple.
rozcietrzewiacz
Il n'y a rien d'idéologique dans ma recommandation. L'alias rm est indirectement responsable de nombreux fichiers perdus (j'ai rencontré de nombreuses victimes de cet alias). Je soupçonnais le mkdir d'avoir, dans une bien moindre mesure, des effets secondaires indésirables. Bien sûr, je ne suis pas contre les changements cosmétiques, pas comportementaux, comme vos exemples ssh et ls.
jlliagre
16

Bien sûr, on pourrait faire valoir que la création du répertoire parent devrait être la valeur par défaut et une option de vérification pourrait être utilisée pour empêcher la création du répertoire si le parent n'existe pas.

Mais la raison pour laquelle c'est l'inverse n'est que de l'histoire. La version de base de mkdir n'a pas créé de répertoires parents. C'est pourquoi les distributions X11 sont arrivées avec une commande nommée mkdirhier qui a pu remplir cette tâche: vérifier si les répertoires parents existent et les créer si nécessaire.

Plus tard, cette fonctionnalité a été ajoutée à la commande mkdir sur de nombreuses versions UNIX (je ne sais pas si elle est dans le standard POSIX de nos jours). Pour maintenir la compatibilité de cette fonctionnalité a été mis à la disposition en activant un drapeau d'option: -p.

Pourquoi est-il mauvais de l'avoir activé par défaut? Les scripts peuvent s'appuyer sur l' échec de mkdir si le répertoire parent n'existe pas. Surtout en tant qu'utilisateur root, il peut être dangereux de créer des arborescences de répertoires par défaut.

Exemple:

 if mkdir /backup/$(uname -n)/$(date +%Y%m%d)
  then
    perform_backup ...

Dans cet exemple, le répertoire serait créé et la sauvegarde effectuée même si le système de fichiers /backupn'est pas monté et le parent /backup/$(uname -n)n'existe pas si la valeur par défaut est l'inverse.

Règle générale: il est recommandé de ne pas modifier le comportement par défaut d'un outil. Si vous le souhaitez, fournissez des options pour permettre de modifier le comportement par défaut.

ktf
la source
2
J'aime l'exemple de montage que vous avez utilisé ici. Je n'avais pas pensé à ce scénario particulier.
Treffynnon
1
Les options -p (et -m) ont été introduites par System V en 1983. Les deux font définitivement partie de la norme POSIX.
jlliagre
4

Je pense que c'est un peu la philosophie. La commande nue mkdir (1) (sans options) représente l' appel système mkdir (2) , fournissant ses fonctionnalités dans le shell, ne faisant ni plus ni moins.

ern0
la source
4

Au début , il n'y avait que la simple mkdircommande. Conformément aux principes de conception d'Unix, cette commande simple a effectué une tâche simple: créer un répertoire.

Plus tard, mkdiracquis une -poption pour gérer un cas d'utilisation courant où l'appelant veut créer zéro, un ou plusieurs répertoires pour s'assurer qu'un chemin particulier existe. Cette opération n'a pas été effectuée par défaut pour plusieurs raisons. Tout d'abord, tous les systèmes n'avaient pas cette fonctionnalité plus complexe, et nécessitant l' -poption signifiait que les scripts qui l'utilisaient recevraient un message d'erreur raisonnable (quelque chose comme mkdir: invalid option -z) plutôt que de ne pas étrangement échouer à créer des répertoires de temps en temps. Deuxièmement, et surtout, le comportement de mkdir -pn'est pas un remplacement compatible de mkdirdans tous les cas.

En particulier, sur la plupart des systèmes de fichiers, mkdirest une opération atomique . Si un programme s'exécute mkdir playgroundet que la commande réussit, le programme sait qu'il a créé le playgroundrépertoire. Cela permet au programme de traiter le nouveau répertoire comme son terrain de jeu exclusif: si une autre instance du même programme s'exécute simultanément, son appel à mkdir playgroundéchouera. Cette propriété n'est évidemment pas fournie par mkdir -pcar elle permet à l'argument d'exister.

Si elle mkdir -pexistait depuis le début, elle aurait pu être mise en mode par défaut, avec quelque chose comme mkdir -apour la commande de création de répertoire unique. Mais cela n'aurait pas suivi la philosophie de conception Unix habituelle: la plupart des utilitaires de base sont de simples wrappers autour des primitives sous-jacentes, avec un comportement plus sophistiqué (comme la création de plusieurs répertoires en une seule fois) nécessitant des options fantaisistes.

Gilles 'SO- arrête d'être méchant'
la source
2

Pour moi, le problème est que le comportement de l'option -p si elle était la valeur par défaut est essentiellement un effet secondaire. Il ajoute de la complexité à une commande en faisant quelque chose de plus que ce que vous lui avez demandé de faire. C'est encore une chose invisible à retenir. L'une des règles de base d'une bonne pratique de programmation est d'éviter les effets secondaires.

Les langages de programmation modernes sont si puissants qu'il est relativement facile de créer n'importe quelle commande complexe dont vous pourriez avoir besoin à partir des primitives fournies par un langage. Pour ce faire, il faut prendre une décision consciente sur le comportement requis et laisser un enregistrement concret et visible de ce qui a été fait.

Joe
la source