Warum ist bei mkdir das Flag -p nicht standardmäßig gesetzt, um die Erstellung verschachtelter Verzeichnisse zu ermöglichen?


11

Ich sehe keinen Grund, warum das -pFlag mkdirnicht standardmäßig gesetzt sein sollte.

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

Es ist ein zerstörungsfreier Befehl, soweit ich sehen kann. Habe ich etwas Wichtiges an der Funktionsweise verpasst?

Zweitens gibt es eine einfache Möglichkeit, dies zum Standardverhalten von zu machen mkdir?


2
Geben Sie dies in Ihre .bashrc ein : alias mkdir="mkdir -p".
Kevin

Nach all der Diskussion habe ich mich entschieden, mit einem Alias ​​vonmkdp
Treffynnon

Antworten:


6

Dies ist eine optionale Funktion, die nicht immer erwünscht ist - insbesondere in Skripten. Beachten Sie bei Skripten die folgenden Nachteile:

  • Die Tatsache, dass das Verzeichnis bereits vorhanden ist, wird nicht gemeldet: Wenn ein Skript einige Dateien in einem neu erstellten Verzeichnis ablegen soll und dieses Verzeichnis bereits vorhanden ist und Dateien enthält, kann das Skript viel Chaos verursachen. (Es wird mühsam sein, später die Dateien herauszufiltern, die vom Skript dort abgelegt wurden.)
  • Auf der anderen Seite kann ein Skript (oder ein Teil davon) von einer zuvor erstellten Verzeichnisstruktur abhängen (möglicherweise von einem anderen Paket / Skript). Beispielsweise muss ein Paketinstallationsskript möglicherweise Bibliotheken in ein Unterverzeichnis stellen /usr/local/lib/GreatSoftware/ImportantPartOfIt, aber die Bibliotheken hängen von / link to stuff unter ab /usr/local/lib/GreatSoftware. Wenn dies fehlt, sollte das Skript nicht fortgesetzt werden.

Das generische Verhalten von mkdirmacht es einfach und natürlich, da solche Situationen gemeldet werden und sofort erfasst werden können.


Sie können einen Alias ​​dafür erstellen, wenn Sie ihn immer mkdir -pin Ihren Shells verwenden möchten :

alias mkdir='mkdir -p'

(Dies sollte zu Ihrer .bashrcoder einer anderen Konfiguration gehen, die Ihre Shell verwendet.)


1
Ich würde nicht vorschlagen, einen Standardbefehl als Alias ​​zu verwenden, damit er sich nicht standardmäßig verhält. Das würde die Skripte nicht portierbar machen und die Leser verwirren. Es alias mkdp="mkdir -p"wäre ratsamer, einen neuen Alias ​​oder eine neue Funktion zu erstellen.
Jlliagre

2
@jlliagre Nein, es würde die Skripte nicht beeinflussen. Lokal definierte Aliase .bashrcwirken sich (normalerweise) nicht auf ihre Umgebung aus.
Rozcietrzewiacz

In der Tat, aber Sie haben meinen Standpunkt verfehlt. Das Aliasing eines Standardbefehls zur Änderung seines Verhaltens, auch für den eigenen Gebrauch, wird nicht empfohlen. Das schlimmste Beispiel ist das Allgegenwärtige alias rm='rm -i'.
Jlliagre

1
@jlliagre Von wem nicht empfohlen? ;) Aber ja, ich stimme zu, ich würde selbst lieber einen anderen Alias ​​verwenden - aber aus praktischen, nicht ideologischen Gründen. Ich denke auch nicht, dass rm -iAlias ​​immer schlecht ist - obwohl dies zu schlechten Gewohnheiten führen könnte. Sicherlich sind nicht alle Befehls-Aliase gleich gut / schlecht - überlegen Sie ls="ls --color=auto"oder ssh="TERM=xterm ssh"zum Beispiel.
Rozcietrzewiacz

In meiner Empfehlung ist nichts Ideologisches. Der rm-Alias ​​ist indirekt für viele verlorene Dateien verantwortlich (ich habe viele Opfer dieses Alias ​​getroffen). Ich vermutete, dass der mkdir in viel geringerem Maße unerwünschte Nebenwirkungen hatte. Natürlich bin ich nicht gegen kosmetische, nicht gegen Verhaltensänderungen wie Ihre ssh- und ls-Beispiele.
Jlliagre

16

Natürlich könnte man argumentieren, dass die Erstellung eines übergeordneten Verzeichnisses die Standardeinstellung sein sollte, und eine Prüfoption könnte verwendet werden, um die Erstellung eines Verzeichnisses zu verhindern, wenn das übergeordnete Verzeichnis nicht vorhanden ist.

Aber der Grund, warum es umgekehrt ist, ist nur Geschichte. Die Basisversion von mkdir hat keine übergeordneten Verzeichnisse erstellt. Aus diesem Grund wurden die X11-Distributionen mit einem Befehl namens mkdirhier geliefert, der diese Aufgabe erfüllen konnte: Überprüfen Sie, ob die übergeordneten Verzeichnisse vorhanden sind, und erstellen Sie sie, falls erforderlich.

Später wurde diese Funktionalität in vielen UNIX-Versionen zum Befehl mkdir hinzugefügt (ich weiß nicht, ob sie heutzutage im POSIX-Standard enthalten ist). Um die Kompatibilität aufrechtzuerhalten, wurde diese Funktion durch Aktivieren eines Optionsflags verfügbar gemacht : -p.

Warum ist es schlecht, wenn es standardmäßig aktiviert ist? Skripte können davon abhängen, dass mkdir fehlschlägt, wenn das übergeordnete Verzeichnis nicht vorhanden ist. Insbesondere als Benutzer root kann es gefährlich sein, standardmäßig Verzeichnisbäume zu erstellen.

Beispiel:

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

In diesem Beispiel wird das Verzeichnis erstellt und die Sicherung auch dann durchgeführt, wenn das Dateisystem /backupnicht bereitgestellt ist und das übergeordnete Verzeichnis /backup/$(uname -n)nicht vorhanden ist, wenn die Standardeinstellung umgekehrt wäre.

Faustregel: Es wird empfohlen, das Standardverhalten eines Werkzeugs nicht zu ändern. Geben Sie bei Bedarf Optionen an, mit denen Sie das Standardverhalten ändern können.


2
Ich mag das Mount-Beispiel, das Sie hier verwendet haben. Ich hatte nicht an dieses spezielle Szenario gedacht.
Treffynnon

1
Die Optionen -p (und -m) wurden 1983 von System V eingeführt. Beide sind definitiv Teil des POSIX-Standards.
Jlliagre

4

Ich denke, das ist eine Art Philosophie. Der Befehl bare mkdir (1) (ohne Optionen) stellt den Systemaufruf mkdir (2) dar und stellt seine Funktionalität in der Shell bereit , ohne mehr oder weniger zu tun.


4

Am Anfang gab es nur den bloßen mkdirBefehl. In Übereinstimmung mit den Entwurfsprinzipien von Unix führte dieser einfache Befehl eine einfache Aufgabe aus: das Erstellen eines Verzeichnisses.

Später wurde mkdireine -pOption erworben, um einen allgemeinen Anwendungsfall zu behandeln, bei dem der Aufrufer null, ein oder mehrere Verzeichnisse erstellen möchte, um sicherzustellen, dass ein bestimmter Pfad vorhanden ist. Dies wurde aus mehreren Gründen nicht zur Standardoperation gemacht. Erstens hatten nicht alle Systeme diese komplexere Funktion, und das Erfordernis der -pOption bedeutete, dass Skripte, die sie verwendeten, eine vernünftige Fehlermeldung (so etwas wie mkdir: invalid option -z) erhielten, anstatt seltsamerweise gelegentlich keine Verzeichnisse zu erstellen. Zweitens und vor allem ist das Verhalten von mkdir -pnicht mkdirin allen Fällen ein kompatibler Ersatz .

Insbesondere ist bei den meisten Dateisystemen mkdireine atomare Operation . Wenn ein Programm ausgeführt wird mkdir playgroundund der Befehl erfolgreich ist, weiß das Programm, dass es das playgroundVerzeichnis erstellt hat. Auf diese Weise kann das Programm das neue Verzeichnis als exklusiven Spielplatz behandeln: Wenn eine andere Instanz desselben Programms gleichzeitig ausgeführt wird, schlägt der Aufruf von mkdir playgroundfehl. Diese Eigenschaft wird offensichtlich nicht von bereitgestellt, mkdir -pda das Argument vorhanden sein kann.

Wenn mkdir -pes von Anfang an existiert hätte, hätte es zum Standardmodus gemacht werden können, etwa mkdir -afür den Befehl zum Erstellen eines einzelnen Verzeichnisses. Dies wäre jedoch nicht der üblichen Unix-Designphilosophie gefolgt: Die meisten grundlegenden Dienstprogramme sind einfache Wrapper um die zugrunde liegenden Grundelemente, wobei ein ausgefalleneres Verhalten (wie das Erstellen mehrerer Verzeichnisse auf einmal) ausgefallene Optionen erfordert.


2

Für mich ist das Problem, dass das Verhalten der Option -p, wenn es die Standardeinstellung wäre, im Wesentlichen ein Nebeneffekt ist. Es erhöht die Komplexität eines Befehls, indem es etwas zusätzlich zu dem tut, was Sie von ihm verlangt haben. Es ist eine weitere unsichtbare Sache, an die man sich erinnern muss. Eine der Grundregeln der Soundprogrammierungspraxis besteht darin, Nebenwirkungen zu vermeiden.

Moderne Programmiersprachen sind so leistungsfähig, dass es relativ einfach ist, aus den Grundelementen einer Sprache einen komplexen Befehl zu erstellen, den Sie möglicherweise benötigen. Dies beinhaltet eine bewusste Entscheidung darüber, welches Verhalten erforderlich ist, und hinterlässt eine konkrete, sichtbare Aufzeichnung dessen, was getan wurde.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.