Ich habe das folgende Skript verwendet, um festzustellen, ob eine Datei vorhanden ist:
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi
Was ist die richtige Syntax, wenn ich nur prüfen möchte, ob die Datei existiert nicht?
#!/bin/bash
FILE=$1
if [ $FILE does not exist ]; then
echo "File $FILE does not exist."
fi
Der test Befehl ([
hier) hat einen "nicht" logischen Operator, der das Ausrufezeichen ist (ähnlich wie in vielen anderen Sprachen). Versuche dies:
if [ ! -f /tmp/foo.txt ]; then
echo "File not found!"
fi
Bash File Testing
-b filename
- Spezielle Datei blockieren-c filename
- Sonderzeichendatei-d directoryname
- Auf Verzeichnisexistenz prüfen-e filename
- Auf Vorhandensein von Dateien prüfen, unabhängig vom Typ (Knoten, Verzeichnis, Socket usw.)-f filename
- Überprüfen Sie, ob eine reguläre Datei existiert, kein Verzeichnis-G filename
- Überprüfen Sie, ob die Datei vorhanden ist und der gültigen Gruppen-ID gehört-G filename set-group-id
- True, wenn die Datei existiert und die Gruppen-ID gesetzt ist-k filename
- Etwas klebrig-L filename
- Symbolischer Link-O filename
- True, wenn die Datei existiert und der effektiven Benutzer-ID gehört-r filename
- Überprüfen Sie, ob die Datei lesbar ist-S filename
- Überprüfen Sie, ob die Datei ein Socket ist-s filename
- Überprüfen Sie, ob die Datei eine Größe ungleich Null hat-u filename
- Überprüfen Sie, ob das Bit "Datei Set-User-ID" gesetzt ist-w filename
- Überprüfen Sie, ob die Datei beschreibbar ist-x filename
- Überprüfen Sie, ob die Datei ausführbar ist
Wie benutzt man:
#!/bin/bash
file=./file
if [ -e "$file" ]; then
echo "File exists"
else
echo "File does not exist"
fi
Ein Testausdruck kann mit dem !
-Operator negiert werden
#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
echo "File does not exist"
else
echo "File exists"
fi
Sie können einen Ausdruck mit "!" Negieren:
#!/bin/bash
FILE=$1
if [ ! -f "$FILE" ]
then
echo "File $FILE does not exist"
fi
Die relevante Manpage ist man test
oder entsprechend man [
- oder help test
oder help [
für den eingebauten Bash-Befehl.
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"
Es ist auch möglich, dass die Datei eine unterbrochene symbolische Verknüpfung oder eine nicht reguläre Datei ist, wie z. eine buchse, ein gerät oder ein fifo. So fügen Sie beispielsweise eine Überprüfung auf fehlerhafte Symlinks hinzu:
if [[ ! -f $FILE ]]; then
if [[ -L $FILE ]]; then
printf '%s is a broken symlink!\n' "$FILE"
else
printf '%s does not exist!\n' "$FILE"
fi
fi
Erwähnenswert ist, dass Sie einen einzelnen Befehl abkürzen können, wenn Sie ihn ausführen müssen
if [ ! -f "$file" ]; then
echo "$file"
fi
zu
test -f "$file" || echo "$file"
oder
[ -f "$file" ] || echo "$file"
Ich bevorzuge den folgenden Einzeiler im POSIX Shell-kompatiblen Format:
$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
Für ein paar Befehle, wie ich es in einem Skript tun würde:
$ [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
Sobald ich damit angefangen habe, verwende ich selten mehr die vollständig typisierte Syntax !!
Um die Existenz einer Datei zu testen, kann der Parameter einer der folgenden sein:
-e: Returns true if file exists (regular file, directory, or symlink)
-f: Returns true if file exists and is a regular file
-d: Returns true if file exists and is a directory
-h: Returns true if file exists and is a symlink
Alle folgenden Tests gelten für reguläre Dateien, Verzeichnisse und Symlinks:
-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0
Beispielskript:
#!/bin/bash
FILE=$1
if [ -f "$FILE" ]; then
echo "File $FILE exists"
else
echo "File $FILE does not exist"
fi
Du kannst das:
[[ ! -f "$FILE" ]] && echo "File doesn't exist"
oder
if [[ ! -f "$FILE" ]]; then
echo "File doesn't exist"
fi
Wenn Sie nach Dateien und Ordnern suchen möchten, verwenden Sie die Option -e
anstelle von -f
. -e
liefert true für reguläre Dateien, Verzeichnisse, Sockets, Character Special Files, Block Special Files etc.
Sie sollten beim Ausführen von test
für eine Variable ohne Anführungszeichen vorsichtig sein, da dies zu unerwarteten Ergebnissen führen kann:
$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1
In der Regel wird empfohlen, die getestete Variable in doppelte Anführungszeichen zu setzen:
#!/bin/sh
FILE=$1
if [ ! -f "$FILE" ]
then
echo "File $FILE does not exist."
fi
Es gibt drei Möglichkeiten, dies zu tun:
Negiere den Exit-Status mit bash (keine andere Antwort hat dies gesagt):
if ! [ -e "$file" ]; then
echo "file does not exist"
fi
Oder:
! [ -e "$file" ] && echo "file does not exist"
Negieren Sie den Test innerhalb des Testbefehls [
(so haben die meisten Antworten zuvor präsentiert):
if [ ! -e "$file" ]; then
echo "file does not exist"
fi
Oder:
[ ! -e "$file" ] && echo "file does not exist"
Handeln Sie, wenn das Testergebnis negativ ist (||
anstelle von &&
):
Nur:
[ -e "$file" ] || echo "file does not exist"
Dies sieht albern aus (IMO). Verwenden Sie es nur, wenn Ihr Code auf die Bourne-Shell portierbar sein muss (wie der /bin/sh
von Solaris 10 oder früher), dem der Pipeline-Negierungsoperator (!
) fehlte. :
if [ -e "$file" ]; then
:
else
echo "file does not exist"
fi
Im
[ -f "$file" ]
der Befehl [
führt einen Systemaufruf stat()
(nicht lstat()
) auf dem in $file
gespeicherten Pfad aus und gibt true zurück, wenn dieser Systemaufruf erfolgreich ist und der Typ von Die von stat()
zurückgegebene Datei ist " regular ".
Wenn also [ -f "$file" ]
true zurückgibt, können Sie feststellen, dass die Datei existiert und eine reguläre Datei oder ein Symlink ist, der schließlich in eine reguläre Datei aufgelöst wird (oder zumindest zum Zeitpunkt der stat()
).
Wenn es jedoch false zurückgibt (oder wenn [ ! -f "$file" ]
oder ! [ -f "$file" ]
true zurückgibt), gibt es viele verschiedene Möglichkeiten:
stat()
fehlschlagen kann.Kurz gesagt sollte es sein:
if [ -f "$file" ]; then
printf '"%s" is a path to a regular file or symlink to regular file\n' "$file"
Elif [ -e "$file" ]; then
printf '"%s" exists but is not a regular file\n' "$file"
Elif [ -L "$file" ]; then
printf '"%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n' "$file"
else
printf 'I cannot tell if "%s" exists, let alone whether it is a regular file or not\n' "$file"
fi
Um sicherzugehen, dass die Datei nicht existiert, benötigen wir den Systemaufruf stat()
, um den Fehlercode ENOENT
zurückzugeben (ENOTDIR
gibt an, dass sich eine der Pfadkomponenten befindet kein Verzeichnis ist ein anderer Fall, in dem wir feststellen können, dass die Datei über diesen Pfad nicht existiert). Leider lässt uns der Befehl [
das nicht wissen. Es wird false zurückgegeben, ob der Fehlercode ENOENT, EACCESS (Berechtigung verweigert), ENAMETOOLONG oder etwas anderes ist.
Der [ -e "$file" ]
-Test kann auch mit ls -Ld -- "$file" > /dev/null
durchgeführt werden. In diesem Fall gibt ls
an, warum stat()
fehlgeschlagen ist, obwohl die Informationen nicht einfach programmgesteuert verwendet werden können:
$ file=/var/spool/cron/crontabs/root
$ if [ ! -e "$file" ]; then echo does not exist; fi
does not exist
$ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
ls: cannot access '/var/spool/cron/crontabs/root': Permission denied
stat failed
Zumindest sagt ls
, dass es nicht daran liegt, dass die Datei nicht existiert, dass sie fehlschlägt. Dies liegt daran, dass nicht festgestellt werden kann, ob die Datei vorhanden ist oder nicht. Der Befehl [
hat das Problem einfach ignoriert.
Mit der Shell zsh
können Sie den Fehlercode mit der Sondervariablen $ERRNO
nach dem fehlgeschlagenen Befehl [
abfragen und diese Zahl mit dem Sonderarray $errnos
im Modul zsh/system
dekodieren:
zmodload zsh/system
ERRNO=0
if [ ! -f "$file" ]; then
err=$ERRNO
case $errnos[err] in
("") echo exists, not a regular file;;
(ENOENT|ENOTDIR)
if [ -L "$file" ]; then
echo broken link
else
echo does not exist
fi;;
(*) syserror -p "can't tell: " "$err"
esac
fi
(Beachten Sie, dass die $errnos
-Unterstützung bei einigen Versionen von zsh
unterbrochen war, als sie mit neueren Versionen von gcc
erstellt wurden ).
Verwenden Sie "!", Um einen Test umzukehren. Dies entspricht dem logischen Operator "nicht" in anderen Sprachen. Versuche dies:
if [ ! -f /tmp/foo.txt ];
then
echo "File not found!"
fi
Oder anders geschrieben:
if [ ! -f /tmp/foo.txt ]
then echo "File not found!"
fi
Oder Sie könnten verwenden:
if ! [ -f /tmp/foo.txt ]
then echo "File not found!"
fi
Oder alles zusammen:
if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi
Was kann geschrieben werden (mit dann "und" Operator: &&) als:
[ ! -f /tmp/foo.txt ] && echo "File not found!"
Was so kürzer aussieht:
[ -f /tmp/foo.txt ] || echo "File not found!"
Dieser Code funktioniert auch.
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File '$FILE' Exists"
else
echo "The File '$FILE' Does Not Exist"
fi
Das test
Ding kann auch zählen. Es hat bei mir funktioniert (basierend auf Bash Shell: Check File Exists or Not):
test -e FILENAME && echo "File exists" || echo "File doesn't exist"
Der einfachste Weg
FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
Dieses Shell-Skript kann auch zum Suchen einer Datei in einem Verzeichnis verwendet werden:
echo "enter file"
read -r a
if [ -s /home/trainee02/"$a" ]
then
echo "yes. file is there."
else
echo "sorry. file is not there."
fi
manchmal kann es nützlich sein, && und || zu verwenden Betreiber.
Wie in (wenn Sie den Befehl "test" haben):
test -b $FILE && echo File not there!
oder
test -b $FILE || echo File there!
Wenn Sie test
anstelle von []
verwenden möchten, können Sie !
verwenden, um die Negation zu erhalten:
if ! test "$FILE"; then
echo "does not exist"
fi
Sie können auch mehrere Befehle in einer Zeile gruppieren
[ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )
oder
[ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}
Wenn Dateiname nicht beendet wird, erfolgt die Ausgabe
test1
test2
test3
Hinweis: (...) wird in einer Subshell ausgeführt, {...;} wird in derselben Shell ausgeführt. Die geschweifte Klammer funktioniert nur in Bash.