So überprüfen Sie, ob eine Datei in Linux-Bash-Skripten vorhanden ist
Veröffentlicht: 2022-08-18Wenn ein Linux-Bash-Skript darauf angewiesen ist, dass bestimmte Dateien oder Verzeichnisse vorhanden sind, kann es nicht einfach davon ausgehen, dass dies der Fall ist. Es muss überprüft werden, ob sie definitiv vorhanden sind. Hier ist, wie das geht.
Nehmen Sie nichts an
Wenn Sie ein Skript schreiben, können Sie keine Annahmen darüber treffen, was auf einem Computer vorhanden ist und was nicht. Das gilt in doppelter Hinsicht, wenn das Skript verteilt und auf vielen verschiedenen Computern ausgeführt werden soll. Früher oder später wird das Skript auf einem Computer ausgeführt, der Ihren Annahmen nicht entspricht, und das Skript schlägt fehl oder wird unvorhersehbar ausgeführt.
Alles, was wir auf einem Computer erstellen oder schätzen, wird in einer Datei eines bestimmten Formats gespeichert, und alle diese Dateien befinden sich in einem Verzeichnis. Skripte können Dateien und Verzeichnisse lesen, schreiben, umbenennen, löschen und verschieben – alles Dinge, die Sie auf der Befehlszeile tun können.
Der Vorteil, den Sie als Mensch haben, ist, dass Sie den Inhalt eines Verzeichnisses sehen können und wissen, ob eine Datei existiert oder nicht – oder ob das erwartete Verzeichnis überhaupt existiert. Wenn ein Skript beim Manipulieren von Dateien einen Fehler verursacht, kann dies schwerwiegende und schädliche Folgen haben.
Bash bietet eine umfassende Reihe von Tests, mit denen Sie Dateien und Verzeichnisse erkennen und auf viele ihrer Attribute testen können. Diese in Skripte zu integrieren ist einfach, aber die Vorteile in Bezug auf Robustheit und Feinsteuerung sind beträchtlich.
VERWANDT: So verwenden Sie bedingte Tests mit doppelten Klammern in Linux
Die Bandbreite der Tests
Indem wir die if-Anweisung mit dem entsprechenden Test aus einer großen Sammlung von Datei- und Verzeichnistests kombinieren, können wir leicht feststellen, ob eine Datei existiert, ob sie ausführbar oder beschreibbar ist und vieles mehr.
- -b : Gibt wahr zurück, wenn die Datei eine spezielle Blockdatei ist.
- -c : Gibt wahr zurück, wenn die Datei zeichenspezifisch ist.
- -d : Gibt wahr zurück, wenn die „Datei“ ein Verzeichnis ist.
- -e : Gibt wahr zurück, wenn die Datei existiert.
- -f : Gibt true zurück, wenn die Datei existiert und eine reguläre Datei ist.
- -g : Gibt „true“ zurück, wenn die Datei die Berechtigung
setgid
hat (chmod g+
). - -h : Gibt true zurück, wenn die Datei ein symbolischer Link ist.
- -L : Gibt true zurück, wenn die Datei ein symbolischer Link ist.
- -k : Gibt wahr zurück, wenn sein Sticky-Bit gesetzt ist (
chmod +t
). - -p : Gibt true zurück, wenn die Datei eine benannte Pipe ist.
- -r : Gibt true zurück, wenn die Datei lesbar ist.
- -s : Gibt true zurück, wenn die Datei existiert und nicht leer ist.
- -S : Gibt wahr zurück, wenn die Datei ein Socket ist.
- -t : Gibt true zurück, wenn der Dateideskriptor in einem Terminal geöffnet wird.
- -u : Gibt „true“ zurück, wenn die Datei die Berechtigung
setuid
hat (chmod u+
). - -w : Gibt true zurück, wenn die Datei beschreibbar ist.
- -x : Gibt true zurück, wenn die Datei ausführbar ist.
- -O : Gibt true zurück, wenn Ihnen gehört.
- -G : Gibt true zurück, wenn das Eigentum Ihrer Gruppe ist.
- -N : Gibt true zurück, wenn die Datei seit dem letzten Lesen geändert wurde.
- ! : Der logische NOT-Operator.
- && : Der logische UND-Operator.
- || : Der logische ODER-Operator.
Die Liste beginnt mit -b
, weil der -a
-Test veraltet ist und durch den -e
-Test ersetzt wurde.
RELATED: So verwenden Sie SUID, SGID und Sticky Bits unter Linux
Verwenden der Tests in Skripten
Die generische Datei test if
-Anweisung ist ein einfaches Skriptkonstrukt. Der Vergleich innerhalb der doppelten Klammern „ [[ ]]
“ verwendet den -f
-Test, um festzustellen, ob eine reguläre Datei mit diesem Namen existiert.
Kopieren Sie den Text dieses Skripts in einen Editor und speichern Sie ihn in einer Datei namens „script1.sh“ und verwenden Sie chmod
, um ihn ausführbar zu machen.
#!/bin/bash wenn [[ -f $1 ]] dann echo "Die Datei $1 existiert." anders echo "Die Datei $1 kann nicht gefunden werden." fi
Sie müssen den Namen der Datei auf der Kommandozeile an das Skript übergeben.
chmod +x script1.sh
Sie müssen dies mit jedem Skript tun, wenn Sie die anderen Beispiele aus dem Artikel ausprobieren möchten.
Lassen Sie uns das Skript an einer einfachen Textdatei ausprobieren.
./script1.sh Testdatei.txt
Die Datei existiert und das Skript meldet diese Tatsache korrekt. Wenn wir die Datei löschen und es erneut versuchen, sollte der Test fehlschlagen und das Skript sollte uns dies melden.
./script1.sh Testdatei.txt
In einer realen Situation müsste Ihr Skript alle angemessenen Maßnahmen ergreifen. Vielleicht kennzeichnet es den Fehler und stoppt. Vielleicht erstellt es die Datei und fährt fort. Es kann etwas aus einem Sicherungsverzeichnis kopieren, um die fehlende Datei zu ersetzen. Es hängt alles vom Zweck des Skripts ab. Aber zumindest ist das Skript jetzt in der Lage, die Entscheidung basierend auf dem Wissen zu treffen, ob die Datei vorhanden ist oder nicht.
Das Flag -f
testet, ob die Datei vorhanden ist und ob es sich um eine „normale“ Datei handelt. Mit anderen Worten, es handelt sich nicht um etwas, das wie eine Datei aussieht, aber keine ist, wie z. B. eine Gerätedatei.
Wir werden ls verwenden, um zu überprüfen, ob die Datei „/dev/random“ existiert, und dann sehen, was das Skript daraus macht.
ls -lh /dev/random
./script /dev/random
Da unser Skript auf reguläre Dateien testet und „/dev/random“ eine Gerätedatei ist, schlägt der Test fehl. Um herauszufinden, ob eine Datei existiert, müssen Sie sehr oft sorgfältig auswählen, welchen Test Sie verwenden, oder Sie müssen mehrere Tests verwenden.
Dies ist „script2.sh“, das auf normale Dateien und auf Zeichengerätedateien testet.
#!/bin/bash wenn [[ -f $1 ]] dann echo "Die Datei $1 existiert." anders echo "Die Datei $1 fehlt oder ist keine reguläre Datei." fi wenn [[ -c $1 ]] dann echo "Die Datei $1 ist eine Zeichengerätedatei." anders echo "Die Datei $1 fehlt oder ist keine spezielle Datei." fi
Wenn wir dieses Skript auf der Gerätedatei „/dev/random“ ausführen, schlägt der erste Test wie erwartet fehl und der zweite Test ist erfolgreich. Es erkennt die Datei als Gerätedatei.
./script2.sh /dev/random
Tatsächlich erkennt es es als Zeichengerätedatei . Einige Gerätedateien sind Blockgerätedateien. So wie es aussieht, wird unser Skript damit nicht fertig.
./script2.sh /dev/sda
Wir können den logischen OR
-Operator verwenden und einen weiteren Test in die zweite if-Anweisung einfügen. Unabhängig davon, ob es sich bei der Datei um eine Zeichengerätedatei oder eine Blockgerätedatei handelt, gibt der Test dieses Mal "true" zurück. Dies ist „script3.sh“.
#!/bin/bash wenn [[ -f $1 ]] dann echo "Die Datei $1 existiert." anders echo "Die Datei $1 fehlt oder ist keine reguläre Datei." fi wenn [[ -c $1 || -b $1 ]] dann echo "Die Datei $1 ist eine Zeichen- oder Blockgerätedatei." anders echo "Die Datei $1 fehlt oder ist keine spezielle Datei." fi
Dieses Skript erkennt sowohl Zeichengeräte- als auch Blockgerätedateien.
./script3.sh /dev/random
./script3.sh /dev/sda
Wenn es Ihnen wichtig ist, zwischen den verschiedenen Arten von Gerätedateien zu unterscheiden, können Sie verschachtelte if
-Anweisungen verwenden. Dies ist „script4.sh“.
#!/bin/bash wenn [[ -f $1 ]] dann echo "Die Datei $1 existiert." anders echo "Die Datei $1 fehlt oder ist keine reguläre Datei." fi wenn [[ -c $1 ]] dann echo "Die Datei $1 ist eine Zeichengerätedatei." anders wenn [[ -b $1 ]] dann echo "Die Datei $1 ist eine Blockgerätedatei." anders echo "Die Datei $1 fehlt oder ist keine Gerätedatei." fi fi
Dieses Skript erkennt und kategorisiert sowohl Zeichengeräte- als auch Blockgerätedateien.
./script4.sh /dev/random
./script4.sh /dev/sda
Mit dem logischen UND-Operator können wir auf mehrere Merkmale gleichzeitig testen. Dies ist „script5.sh“. Es prüft, ob eine Datei existiert und das Skript Lese- und Schreibrechte dafür hat.
#!/bin/bash wenn [[ -f $1 && -r $1 && -w $1 ]] dann echo "Die Datei $1 existiert und wir haben Lese-/Schreibrechte." anders echo "Die Datei $1 fehlt, keine normale Datei, oder wir können sie nicht lesen/schreiben." fi
Wir führen das Skript auf einer Datei aus, die uns gehört, und einer, die zu root
gehört.
./script5.sh .bashrc
./script5.sh /etc/fstab
Um zu testen, ob ein Verzeichnis vorhanden ist, verwenden Sie den Test -d
. Dies ist „script6.sh“. Es ist Teil eines Backup-Skripts. Als erstes prüft es, ob das auf der Kommandozeile übergebene Verzeichnis existiert oder nicht. Es verwendet den logischen NOT
Operator !
im if
-Anweisungstest.
#!/bin/bash wenn [[ ! -d $1 ]] dann echo "Sicherungsverzeichnis erstellen:" $1 mkdir $1 wenn [[ ! $? -eq 0 ]] dann echo "Sicherungsverzeichnis konnte nicht erstellt werden:" $1 Ausfahrt fi anders echo "Backup-Verzeichnis existiert." fi # mit Dateisicherung fortfahren echo "Backup bis: "$1
Wenn das Verzeichnis nicht existiert, wird es erstellt. Wenn die Verzeichniserstellungsdateien vorliegen, wird das Skript beendet. Wenn die Erstellung des Verzeichnisses erfolgreich ist oder das Verzeichnis bereits existiert, fährt das Skript mit seinen Backup-Aktionen fort.
Wir führen das Skript aus und prüfen dann mit ls
und der Option -d
(Verzeichnis), ob das Backup-Verzeichnis existiert.
./script6.sh Dokumente/Projektsicherung
ls -d Dokumente/Projektsicherung
Das Sicherungsverzeichnis wurde erstellt. Wenn wir das Skript erneut ausführen, sollte es melden, dass das Verzeichnis bereits vorhanden ist.
./script6.sh
Das Skript findet das Verzeichnis und fährt mit der Durchführung der Sicherung fort.
Testen, nicht annehmen
Früher oder später werden Annahmen dazu führen, dass schlimme Dinge passieren. Testen Sie zuerst und reagieren Sie entsprechend.
Wissen ist Macht. Verwenden Sie Tests, um Ihren Skripten das nötige Wissen zu vermitteln.
RELATED: So lassen Sie Linux-Skripts erkennen, dass sie in virtuellen Maschinen ausgeführt werden