Shell-Skript, um zu prüfen, ob eine Datei existiert

8

Ich versuche, ein einfaches Skript zu schreiben, das mir sagen wird, ob in $ Temp ein Dateiname existiert, der mit der Zeichenfolge "Test" beginnt.

Zum Beispiel habe ich diese Dateien

%Vor%

Dann möchte ich nur ein Echo geben, dass eine Datei gefunden wurde.

Zum Beispiel so etwas:

%Vor%

Aber das funktioniert nicht.

    
Edward 09.03.2013, 00:13
quelle

7 Antworten

8

Ein Ansatz:

%Vor%

Erläuterung:

  • shopt -s nullglob bewirkt, dass /home/edward/bank1/fiche/Test* auf nothing erweitert wird, wenn keine Datei mit diesem Muster übereinstimmt. (Ohne es wird es intakt bleiben.)
  • ( ... ) richtet eine Untershell ein und verhindert, dass shopt -s nullglob "entweicht".
  • files=(/home/edward/bank1/fiche/Test*) setzt die Dateiliste in ein Array mit dem Namen files . (Beachten Sie, dass dies nur innerhalb der Untershell ist; auf files kann nicht zugegriffen werden, nachdem die Untershell beendet wurde.)
  • "${#files[@]}" ist die Anzahl der Elemente in diesem Array.

Bearbeitet um folgende Frage zu beantworten ("Was ist, wenn ich auch überprüfen muss, ob diese Dateien Daten enthalten und keine Null-Byte-Dateien sind"):

Für diese Version müssen wir -s verwenden (wie Sie es in Ihrer Frage getan haben), die auch auf die Existenz der Datei testet. Es macht also keinen Sinn mehr shopt -s nullglob zu verwenden: Wenn keine Datei dem Muster entspricht, dann -s auf dem Muster wird falsch sein. Also können wir schreiben:

%Vor%

(Hier ist ( ... ) , um zu verhindern, dass file und found_file "entweichen".)

    
ruakh 09.03.2013 00:24
quelle
3

Sie können es in einer Zeile tun:

%Vor%

Um zu verstehen, was es tut, müssen Sie den Befehl zerlegen und ein grundlegendes Bewusstsein für boolesche Logik haben.

Direkt von der Bash-Manpage:

%Vor%

In der Shell (und allgemein in der Unix-Welt) ist der Boolesche Wert true ein Programm, das mit dem Status 0 endet.

ls versucht, das Muster aufzulisten, wenn es erfolgreich ist (dh das Muster existiert), wird es mit dem Status 0, 2 beendet (andernfalls siehe ls man-Seite für Details).

In unserem Fall gibt es tatsächlich 3 Ausdrücke, aus Gründen der Klarheit werde ich Klammern setzen, obwohl sie nicht benötigt werden, weil && auf || Vorrang hat:

%Vor%

Wenn ausdruck1 also wahr ist (dh ls hat das Muster gefunden), wird ausdruck2 ausgewertet (was nur ein Echo ist und mit dem Status 0 endet). In diesem Fall wird expression3 niemals ausgewertet, da das, was sich auf der linken Seite von || befindet, bereits wahr ist und es eine Verschwendung von Ressourcen wäre, zu versuchen, zu bewerten, was rechts ist.

Andernfalls, wenn Ausdruck1 falsch ist, wird Ausdruck2 nicht ausgewertet, aber in diesem Fall ist Ausdruck3.

    
Elisiano Petrini 09.03.2013 00:59
quelle
3

Sie müssen verstehen, wie Unix Ihre Eingabe interpretiert.

Die Standard-Unix-Shell interpoliert Umgebungsvariablen und sogenannte globs , bevor sie die Parameter an Ihr Programm übergibt. Dies unterscheidet sich ein wenig von Windows, wodurch das Programm die Erweiterung interpretiert.

Versuchen Sie Folgendes:

%Vor%

Dies wird alle Dateien und Verzeichnisse in Ihrem aktuellen Verzeichnis wiedergeben. Bevor der Befehl echo ausgeführt wird, interpoliert die Shell die * und erweitert sie und übergibt diesen erweiterten Parameter dann an Ihren Befehl. Sie können es in Aktion sehen, indem Sie dies tun:

%Vor%

Das set -xv schaltet xtrace und verbose ein. Verbose gibt den eingegebenen Befehl zurück und xtrace gibt den Befehl zurück, der ausgeführt wird (dh nach der Shell-Erweiterung).

Versuchen Sie Folgendes:

%Vor%

Beachten Sie, dass durch das Einfügen von Anführungszeichen in den Anführungszeichen der Glob-Ausdruck aus der Shell ausgeblendet wird und die Shell sie nicht erweitern kann. Versuchen Sie Folgendes:

%Vor%

Beachten Sie, dass die Shell Umgebungsvariablen immer noch in doppelte Anführungszeichen, aber nicht in einfache Anführungszeichen erweitern kann.

Sehen wir uns nun Ihre Aussage an:

%Vor%

Die doppelten Anführungszeichen verhindern, dass die Shell den Glob-Ausdruck erweitert, sodass file gleich dem Literal home/edward/bank1/finche/Test* ist. Daher müssen Sie dies tun:

%Vor%

Das Fehlen von Anführungszeichen (und der einleitende Schrägstrich, der wichtig ist!) macht jetzt die Datei gleich mit allen Dateien, die mit diesem Ausdruck übereinstimmen. (Es könnte mehr als eins sein!). Wenn es keine Dateien gibt, kann die Shell, abhängig von der Shell und ihren Einstellungen, die Datei einfach auf diese literale Zeichenfolge setzen.

Sie haben sicherlich die richtige Idee:

%Vor%

Sie können jedoch immer noch gefunden keine zurückgeben, wenn mehr als eine Datei vorhanden ist. Stattdessen erhalten Sie möglicherweise einen Fehler in Ihrem test -Befehl, weil zu viele Parameter vorhanden sind.

Eine Möglichkeit, dies zu umgehen, könnte sein:

%Vor%

In diesem Fall nutze ich den Exit-Code des Befehls ls . Wenn ls eine Datei findet, auf die es zugreifen kann, gibt es einen Null-Exit-Code zurück. Wenn keine übereinstimmende Datei gefunden werden kann, wird ein Beendigungscode ungleich null zurückgegeben. Der Befehl if führt lediglich einen Befehl aus, und wenn der Befehl eine Null zurückgibt, nimmt er die if -Anweisung als true an und führt die if -Klausel aus. Wenn der Befehl einen Wert ungleich null zurückgibt, wird die if -Anweisung als falsch angenommen und die else -Klausel (falls eine verfügbar ist) wird ausgeführt.

Der Befehl test funktioniert in ähnlicher Weise. Wenn test wahr ist, gibt der Befehl test eine Null zurück. Andernfalls gibt der Befehl test einen Wert ungleich null zurück. Das funktioniert großartig mit dem Befehl if . Tatsächlich gibt es einen Alias ​​ für den Befehl test . Versuchen Sie Folgendes:

%Vor%

Der i gibt den Inode aus. Der inode ist die echte ID der Datei. Dateien mit derselben ID sind dieselbe Datei. Sie können sehen, dass /bin/test und /bin/[ derselbe Befehl sind. Dies macht die folgenden zwei Befehle gleich:

%Vor%     
David W. 23.07.2013 03:02
quelle
1
%Vor%     
cleophus_p 29.01.2014 09:13
quelle
0

Das folgende Skript hilft Ihnen, zu einem Prozess zu gehen, wenn dieses Skript in einer angegebenen Variablen existiert,

%Vor%

hier -e dient zum Arbeiten mit Dateien,

ist eine Shell-Variable,

Schlaf für 10 Minuten

Sie können das Skript nach ./waitfor.csh ./temp ; echo "the file exits"

ausführen     
Lakshmi 25.07.2013 04:43
quelle
0

Ein Liner zum Prüfen der Datei existiert oder nicht -

%Vor%     
VIPIN KUMAR 06.10.2016 10:49
quelle
-1

Platzhalter werden nicht innerhalb von Strings in Anführungszeichen erweitert. Und wenn Wildcard erweitert wird, wird es unverändert zurückgegeben, wenn keine Übereinstimmungen vorhanden sind. Es wird nicht in eine leere Zeichenfolge erweitert. Probieren Sie:

%Vor%

Wenn der Platzhalter zu Dateinamen erweitert wurde, zeigt ls sie auf stdout ; Andernfalls wird ein Fehler in stderr und nichts in stdout ausgegeben. Der Inhalt von stdout wird output zugewiesen.

if [ -n "$output" ] prüft, ob $output etwas enthält.

Eine andere Möglichkeit dies zu schreiben wäre:

%Vor%     
Barmar 09.03.2013 00:23
quelle

Tags und Links