Wie führe ich bestimmte Befehle aus, wenn eine Datei NICHT existiert?

8

Ich versuche, das Äquivalent des folgenden C-Codes in Shell-Skripten zu erhalten.

%Vor%

Was ich in diesem Shell-Skript genauer versuche, ist zu überprüfen, ob die Datei nicht existiert und sie dann zu erstellen.

Es tut mir auch sehr leid, wenn dies ein Duplikat einer anderen Frage ist, aber ich wusste wirklich nicht, wie ich danach suchen soll.

    
Dragos Rizescu 24.11.2013, 19:01
quelle

4 Antworten

14

Sie können dies verwenden:

%Vor%     
David Martínez 24.11.2013, 19:07
quelle
16

Die Überprüfung, ob eine Datei existiert, ist eine sehr häufige Aufgabe. Verwenden Sie die Suchleiste (oben rechts), um nach relevanten Fragen zu suchen. Ich habe viele Ergebnisse mit den Begriffen "bash script file exists"

In jedem Fall möchten Sie entweder das test builtin oder sein semantisches Äquivalent [ ] :

%Vor%

oder

%Vor%

was zuerst test das your_file nicht ( ! ) existiert ( -e ) und erstellt wenn es der Fall ist.

Weitere Informationen zu den verschiedenen Tests, die Sie ausführen können (außer -e ), können Sie eingeben:

%Vor%     
Joseph R. 24.11.2013 19:09
quelle
7
%Vor%

Eine einfachere Version wäre einfach touch -- "$path" - sie erstellt die Datei, wenn sie nicht existiert, und aktualisiert nur die Zugriffs- und Änderungszeitpunkte, falls sie existiert. Der doppelte Bindestrich ( -- ) stellt sicher, dass Sie die Datei auch dann erstellen können, wenn sie mit einem Bindestrich beginnt und die Angebote rund um $path sind notwendig.

    
l0b0 24.11.2013 19:06
quelle
7

Tu das nicht, es unterliegt nicht nur den Rennbedingungen, sondern überprüft auch% [ -e /path/file ] , ob du stat(2) für eine Datei machen kannst, also wird es aus verschiedenen Gründen falsch zurückgegeben, nicht nur wegen der Datei kann nicht existieren.

Ein Beispiel ist ein Symlink zu einer Datei, die nicht existiert oder eine Datei in einem Verzeichnis, für das Sie keine Suchberechtigung haben.

Ein viel besserer Ansatz besteht darin, hier die richtigen Flags für den Systemaufruf open(2) zu verwenden, also O_CREAT|O_EXCL . Auf diese Weise schlägt der open() fehl, wenn die Datei nicht bereits existiert, ohne dass Sie mehrere Millionen CPU-Takt-Ticks früher prüfen müssen.

Mit einer Bourne-ähnlichen Shell:

%Vor%

( set -C soll das O_EXCL -Flag aktivieren).

Warum sollten Sie auch eine leere Datei erstellen? Wahrscheinlich möchten Sie etwas in dieser Datei speichern. Dann tu es einfach:

%Vor%

Dann wird diese Befehlsgruppe nur ausgeführt, wenn file noch nicht existiert (und es möglich war, sie zu erstellen).

Wenn Sie auf Datei Existenz testen wollen, schreiben Sie es mindestens:

%Vor%

oder

%Vor%

wenn es Ihnen wichtig ist, dass es sich um einen Symlink handelt. Das gibt immer noch false zurück, wenn die Datei existiert, aber Sie haben nicht das Recht, es zu überprüfen.

Wenn Sie jetzt eine längere und historische Antwort zum Testen auf Dateiexistenz wünschen:

Anfangs war der Befehl test (in Unix v7, wo er zuerst erschien) nein -e (noch -h / -L Option oder -a unary) Option.

Der Weg zum Testen der Dateiexistenz war mit ls . ls (mit -d ) listet die Datei auf und meldet einen Fehler (und gibt einen false Exit-Status zurück), wenn sie die Datei aus irgendeinem Grund nicht nachschlagen kann. Unix hatte ursprünglich keine symbolischen Links, aber wenn sie eingeführt wurden, wurde ls geändert, um lstat(2) für eine Datei anstatt für stat(2) zu erstellen. Das heißt, im Falle von Symlink gibt ls Informationen über die Symlink-Datei selbst zurück, nicht die Datei an dem Pfad, auf den der Symlink zeigt.

Eine Option auf test (aka [ ) zum Testen auf Datei "existence" wurde zuerst in Korn shell test eingebaut . Das war -a , nicht -e . -a ist für zugänglich (glaube ich), was ein genauerer Begriff ist als existing .

Ich weiß nicht wann oder was -e eingeführt hat, möglicherweise POSIX. POSIX sagt , dass -e über -a ausgewählt wurde, um mögliche Verwechslungen mit den% zu vermeiden. co_de% binärer Operator (für und ).

In beiden Fällen versuchen sowohl -a als auch -a eine -e für die Datei, nicht stat(2) . Das ist:

%Vor%

entspricht:

%Vor%

Genau genommen gibt es also true zurück, wenn zum Zeitpunkt des Tests der Pfad nach dem Auflösen der symbolischen Links nachgeschlagen werden konnte, und wenn der lstat(2) fehlschlägt, wird der Grund für den Fehler ignoriert.

stat(2) kann fehlschlagen, wenn die Datei nicht existiert ( stat ), dh wenn die Datei nicht existiert oder existiert, aber ein Symlink zu einer Datei ist, die nicht existiert, aber auch für viele andere Gründe. Ein Blick auf die möglichen Fehlercodes von ENOENT gibt ein paar Ideen:

>
  • stat(2) : Während der Auflösung des Pfads (und das kann eine beliebige Pfadkomponente und der Pfad eines Symlinks sein) haben Sie keine Suche Berechtigung für eine Verzeichniskomponente (beachten Sie, dass Sie möglicherweise weiterhin Zugriff auf die Datei über einen anderen Pfad).
  • EACCESS : Der Pfad konnte nicht aufgelöst werden, weil zu viele Symlinks aufgelöst wurden.
  • %Code%. Zum Beispiel auf ELOOP oder einen Symlink dazu.
Stephane Chazelas 24.11.2013 20:13
quelle

Tags und Links