Vorhandenes Verzeichnis überschreiben?

11

Ich habe einen Verzeichnisnamen fooin ~/Desktop. Angenommen, ich möchte ein Verzeichnis aus einem Terminal mit demselben Namen und demselben Speicherort erstellen. Als ich es versuchte mkdir, gab es einen Fehler:

mkdir: cannot create directory `/home/nux/Desktop/foo': File exists

Das macht Sinn, aber ich möchte ersetzen, foowenn es existiert. Ich habe durchgesehen, man mkdiraber es gibt keine Option, die das tut.

Wie überschreibe ich ein fooVerzeichnis?

Warum gibt es dafür keine mkdirOption?

nux
quelle
Ersetzen foowie beim Löschen aller Inhalte davon? mkdirhat eine -pOption, die ignoriert, ob das Verzeichnis existiert.
Muru
4
Sie möchten also einen Befehl, der alle Dateien in einem Verzeichnis löscht, wenn Sie versehentlich ein neues Verzeichnis mit demselben Namen erstellen? Und Sie fragen sich, warum es keine Option ist? Ist das ein Witz?
Marty Fried
Downvoters klären nur, warum das so ist, und fragen nach einem Befehl, der ein vorhandenes Verzeichnis löscht
Nux
1
@nux für mich macht die frage keinen sinn ... erkläre warum du jemals ein verzeichnis löschen und neu erstellen willst. Wir haben Befehle für alles, was Sie mit dem Verzeichnis tun müssen. mkdir benötigt keine Option zum Entfernen / Neuerstellen.
Rinzwind
1
Ist es hier ein Verbrechen, wenn ich eine logische Frage stelle?
Nux

Antworten:

21

Wenn Ihr Ziel darin besteht, einen einzeiligen Befehl auszuführen, der:

  • Entfernt das Verzeichnis und erstellt ~/Desktop/fooes neu, falls es bereits vorhanden ist.
  • Erstellt das Verzeichnis nur, ~/Desktop/foowenn es noch nicht vorhanden ist.

Dann können Sie verwenden:

rm -r ~/Desktop/foo; mkdir ~/Desktop/foo

; entspricht einer neuen Zeile, ermöglicht jedoch die Ausführung mehrerer Befehle in einer einzelnen Zeile (dh als "einzelner Befehl").

  • Wenn das Verzeichnis, das Sie entfernen, möglicherweise schreibgeschützte Dateien enthält, benötigen Sie das -fFlag, um sie zu entfernen, ohne den Benutzer interaktiv dazu aufzufordern . Das ist in Ordnung, aber ich empfehle besonders vorsichtig zu sein rm -rf .... Siehe man rmfür Details.
  • Sie müssen den rmBefehl beenden, bevor der mkdirBefehl ausgeführt wird. Dies ist der Grund, ;anstatt zu verwenden &. (Ein vorhergehender Befehl wird &asynchron im Hintergrund ausgeführt.)
  • Sie müssen den mkdirBefehl ausführen, wenn der rmBefehl erfolgreich ist. Dies ist der Grund, ;anstatt zu verwenden ||.
  • Sie müssen den mkdirBefehl ausführen, wenn der rmBefehl fehlschlägt (normalerweise bedeutet ein Fehler, dass das Verzeichnis noch nicht vorhanden ist). Dies ist der Grund, ;anstatt zu verwenden &&.
  • Der rmBefehl schlägt möglicherweise auch dann fehl, wenn das Verzeichnis bereits vorhanden ist. In diesem Fall schlägt der mkdirBefehl ebenfalls fehl. Die Fehlermeldungen sind jedoch sinnvoll, und es ist wahrscheinlich nicht erforderlich, einen mittleren Schritt hinzuzufügen, um foodie Existenz zu überprüfen , bevor Sie versuchen, ihn zu erstellen.

Siehe 3.2.3 Listen der Befehle in dem Bash - Referenzhandbuch für weitere Informationen und Erklärungen über die ;, &, ||und &&Betreiber.

Wie von muru vorgeschlagen (und von Rinzwind ausgearbeitet ), empfehle ich Ihnen, zu rsyncprüfen , ob es Ihren Backup-Anforderungen entspricht. Auf der rsync-Dokumentationsseite finden Sie einige zusätzliche nützliche Anleitungen sowie diese Ubuntu-rsync-Anleitung .

Warum hat mkdir diese Option nicht?

mkdirerstellt Verzeichnisse (das "mk" steht für "make" ). Es wäre auch schlecht, Verzeichnisse und alle darin enthaltenen Dateien rekursiv zu löschen, da dies das Prinzip des geringsten Erstaunens in einer Weise verletzen würde, die wahrscheinlich zu Datenverlust führen würde.

rmdirentfernt nicht einmal Verzeichnisse, in denen sich Dateien befinden, die keine Verzeichnisse enthalten. rmhat eine -rOption, die sinnvoll ist, da rmerwartet wird, dass Dateien entfernt werden (das ist ihr Zweck, daher ist die inhärente Gefahr intuitiv und Benutzer wissen normalerweise, dass sie beim Ausführen von rmBefehlen vorsichtig sein müssen ).

Eliah Kagan
quelle
+1 ausgezeichnet. Diese Antwort geht weit über die Erklärung der Syntax hinaus, was ich mir auf Stackexchange-Sites gewünscht hätte. Diese Antwort enthält viele goldene Nuggets.
Govind Rai
7

Nein, es gibt keinen einzigen Befehl, um das zu tun, was Sie verlangen.

Warum?

Dies ist die Unix-Philosophie: Schreiben Sie Programme, die eines tun und es gut machen. Schreiben Sie Programme, um zusammenzuarbeiten. 1

In diesem Fall machen die Befehle mkdirund rmdas, was Sie benötigen, und arbeiten gut zusammen, da rm -rauch das Verzeichnis gelöscht wird, sodass ein nachfolgendes mkdirVerzeichnis erstellt wird.

1 Die Kunst der Unix-Programmierung , Eric S. Raymond, zitiert selbst Doug McIlroy.

muru
quelle
für den Moment ist das eine gute Antwort, ich werde danach suchen
nux
3

Der Befehl zum Entfernen eines Verzeichnisses lautet rm. Sie benötigen also 2 Befehle.

rm -r ~/Desktop/foo/
mkdir ~/Desktop/foo/

Wie in den Kommentaren gezeigt, können Sie sie mit ;(= beides tun, auch wenn das erste fehlschlägt) oder &&(= nur mkdir, wenn das rm nicht ausfällt) verketten.

Das -rdient zum Entfernen von Verzeichnissen. Der 1. Befehl entfernt auch ALLE Inhalte des Verzeichnisses. Wenn dies NICHT Ihre Absicht ist, sind sowohl rm als auch mkdir nicht das, wonach Sie suchen: Berechtigungen sind chmodund chown.

Warum hat mkdir diese Option nicht?

Mehrdeutigkeit. mkdirbedeutet Verzeichnis erstellen. Nicht entfernen und Verzeichnis erstellen. Und da der rmBefehl zum Löschen von Inhalten dient, muss kein rmdirVerzeichnis entfernt werden können.

Rinzwind
quelle
Ich weiß das, aber ich meine einen Befehl, Sie können meine Bearbeitung anzeigen, ich ändere sie
Nux
Erklären Sie zunächst, warum Sie das Verzeichnis neu erstellen müssen. Das macht für mich keinen Sinn.
Rinzwind
Ist mein Bedürfnis sinnvoll, ich frage mich nur wie? es macht Sinn für mich :)
Nux
@nux nein tut es nicht. Und der Betreuer von mkdir versteht auch nicht warum;) Was Sie wollen, ist nutzlos und hat keinen Wert.
Rinzwind
ok, wenn du wissen willst, mache ich ein Skript, um ein Backup in einem neuen Verzeichnis mit dem gleichen Namen von foo zu erstellen und es zu ersetzen, falls vorhanden, um Speicherplatz zu reduzieren
nux
1

Um das so sauber wie möglich zu machen, benutze ich Folgendes:

create_clean_directory(){
    dir_name=$1
    if [ -d "$dir_name" ]; then
        echo "Removing $dir_name"
        rm -rf "$dir_name"
    elif [ -f "$dir_name" ]; then
        echo "File with this name already exists, not a directory."
        exit
    fi
    if mkdir "$dir_name"; then
        echo "Clean directory created: $dir_name"
        return 0
    else
        echo "Creating directory failed: $dir_name"
        return 1
    fi 
}

Und um es zu benutzen:

create_clean_directory <dir_name>

Dadurch wird sichergestellt, dass Sie ein Verzeichnis und keine Datei entfernen möchten:

  1. -dÜberprüfen Sie, ob bereits ein Verzeichnis mit diesem Namen vorhanden ist. Wenn ja, löschen Sie es.

  2. -fStellen Sie sicher, dass keine Datei mit diesem Namen vorhanden ist. Wenn ja, drucken Sie die Fehlermeldung und beenden Sie das Programm.

  3. Erstellen Sie das neue Verzeichnis und geben Sie den Erfolg zurück. Wenn dies fehlschlägt, ist das Echo fehlgeschlagen.

Rea Haas
quelle