Befehl zum Anzeigen einer beliebigen Nachricht, wenn eine bestimmte Datei vorhanden ist

11

Gibt es einen Befehl zum Anzeigen der Meldung "Ja", wenn eine bestimmte Datei vorhanden ist? Wenn die Datei nicht vorhanden ist, müssen keine Funktionen angegeben werden.

James
quelle

Antworten:

25

Verwenden Sie diesen einfachen Bash-Einzeiler:

if [ -e FILENAME ] ; then echo Yes ; fi

Die -ePrüfung wird als wahr ausgewertet, falls FILENAMEvorhanden, unabhängig davon, um was es sich handelt (Datei, Verzeichnis, Link, Gerät, ...).

Wenn Sie nur reguläre Dateien überprüfen möchten, verwenden Sie -fstattdessen, wie @Arronical sagte.

Byte Commander
quelle
18
[ -e FILENAME ] && echo Yes
Zeb McCorkle
@ZebMcCorkle Richtig, das funktioniert auch. Sie können dies als separate Antwort veröffentlichen.
Byte Commander
3
Wenn FILENAMEes sich um eine variable Erweiterung handelt oder Sonderzeichen enthält, vergessen Sie nicht, diese in Anführungszeichen zu setzen. zB in einem Skript , [ -e "$1" ] && echo Yes.
Peter Cordes
@PeterCordes Wenn Sie Bash verwenden, können Sie die Variable verwenden [[und ]]nicht zitieren.
Holloway
1
@Holloway: Ja, aber manchmal müssen Sie tragbare Skripte schreiben, die nur POSIX sh erfordern. Deshalb habe ich eine sichere Version davon gegeben, anstatt sie herunterzustimmen und die Bash-Antwort zu verbessern. Beachten Sie auch, dass es kein Problem ist, Erweiterungen im Inneren zu zitieren. Das [[ ]]Zitieren ist immer eine gute Angewohnheit für Anfänger, die sich nicht an die speziellen Regeln für das Innere des [[ ]]Operators oder für arithmetische Kontexte erinnern .
Peter Cordes
10

Sie können dieses einfache Skript verwenden:

#!/bin/bash

if [[ -f $1 ]]; then
    echo "Yes"
    exit 0
else
    exit 1
fi

Speichern Sie es als file-exists.sh. Geben Sie dann im Terminal Folgendes ein chmod +x file-exists.sh.

Verwenden Sie es wie folgt: ./file-exists.sh FILEWo Sie es durch FILEdie Datei ersetzen, die Sie überprüfen möchten, zum Beispiel:

./file-exists.sh file.txt

Wenn file.txtvorhanden, Yeswird auf dem Terminal gedruckt und das Programm wird mit dem Status 0 (Erfolg) beendet. Wenn die Datei nicht vorhanden ist, wird nichts gedruckt und das Programm wird mit Status 1 beendet (Fehler).

Wenn Sie neugierig sind, warum ich den exitBefehl eingefügt habe , lesen Sie weiter ...


Was ist mit dem exitBefehl los?

exitbewirkt eine normale Prozessbeendigung. Dies bedeutet im Grunde: Es stoppt das Skript. Es akzeptiert einen optionalen (numerischen) Parameter, der den Exit-Status des Skripts darstellt, das ihn aufgerufen hat.

Dieser Beendigungsstatus ermöglicht es Ihren anderen Skripten, Ihr file-existsSkript zu verwenden, und gibt Aufschluss darüber, ob die Datei vorhanden ist oder nicht.

Ein einfaches Beispiel, das dies verwendet, ist dieses Skript (speichern unter file-exists-cli.sh):

#!/bin/bash

echo "Enter a filename and I will tell you if it exists or not: "
read FILE
# Run `file-exists.sh` but discard any output because we don't need it in this example
./file-exists.sh $FILE &>> /dev/null
# #? is a special variable that holds the exit status of the previous command
if [[ $? == 0 ]]; then
    echo "$FILE exists"
else
    echo "$FILE does not exist"
fi

Machen Sie das Übliche chmod +x file-exists-cli.shund führen Sie es dann aus : ./file-exists-cli.sh. Sie werden so etwas sehen:

Datei existiert ( exit 0):

➜  ~ ./file-exists-cli.sh 
Enter a filename and I will tell you if it exists or not: 
booleans.py
booleans.py exists

Datei existiert nicht ( exit 1):

➜  ~ ./file-exists-cli.sh
Enter a filename and I will tell you if it exists or not: 
asdf
asdf does not exist
Grooveplex
quelle
2
Gut, aber du sollst variable Referenzen wie zitieren "$1". Wenn es Leerzeichen enthält, wird es ohne Anführungszeichen unterbrochen und andere schlechte Dinge können passieren.
Joe
9

In der Bash-Shell in der Kommandozeile.

if [[ -f /path/to/file ]]; then echo "Yes"; fi

Dies verwendet den bedingten Bash-Operator -fund prüft, ob die Datei vorhanden ist und eine reguläre Datei ist. Wenn Sie nach Dateien einschließlich Verzeichnissen und Links suchen möchten, verwenden Sie -e.

Dies ist eine großartige Ressource für Bash-Bedingungen.

Arronisch
quelle
1
Warum die Doppelklammern?
Byte Commander
1
Ich bin kein Fan des testOriginalformats, ich weiß, dass es übertrieben ist, aber es ist meine Gewohnheit.
Arronical
7
@ByteCommander: Doppelklammern sind im Allgemeinen besser als Einzelklammern. Sie sind Teil der Shell-Syntax (anstatt den [Befehl aufzurufen , der normalerweise einen integrierten Befehl aufruft). Sie korrigieren Inkonsistenzen und dummes Verhalten der Single-Brace-Version. Das [eingebaute [bleibt aus Kompatibilitätsgründen erhalten, aber ich sehe keinen guten Grund, es in neuem Bash-Code zu verwenden. (Wenn Sie POSIX-kompatible Skripte schreiben müssen, die auf alten Shells oder Ähnlichem ausgeführt werden können, ist das anders.)
Nick Matteo
@kundor: Meistens ist man sich jedoch einig, dass [es zweifelhaft ist , " normalerweise einen eingebauten" zu nennen. type -a [für mich listet "Shell Builtin", dann " /usr/bin/[."
wchargin
1
@wchargin: Ich fürchte, ich verstehe nicht, worauf du hinaus willst. Ihre typeErgebnisse scheinen zu bestätigen, was ich gesagt habe, nein?
Nick Matteo
5

Der kürzeste Befehl, um das zu tun, was Sie wollen, ist:

test -e FILENAME && echo Yes

test -etestet, ob der angegebene Name im Dateisystem vorhanden ist. (Sie können verwenden, test -fum nur auf reguläre Dateien zu beschränken. Weitere man testInformationen finden Sie hier.)

Wenn die angegebene Bedingung als wahr ausgewertet wird, wird testein erfolgreicher Beendigungsstatus zurückgegeben (andernfalls wird ein Fehlerstatus zurückgegeben). Wir kombinieren die beiden Befehle mit &&, was bedeutet, dass "der nächste Befehl ausgeführt wird, wenn der vorherige Befehl mit einem Erfolgsstatus beendet wurde". Der nächste Befehl druckt einfach Yesauf der Standardausgabe. im Falle einer interaktiven Shell auf dem Terminal.

Dies vermeidet das zusätzliche Textmaterial einer ifAussage, führt jedoch zum gleichen Ergebnis. Die Verwendung &&(oder des Gegenteils ||) zum Zusammenbinden von Befehlen funktioniert gut, wenn nur ein einziger Befehl beteiligt ist. Wenn Sie mehr als nur einen einzelnen Befehl als Antwort auf den Exit-Status eines einzelnen Befehls ausführen möchten, ist die Verwendung der ifSyntax schnell besser lesbar.

Wie bereits in anderen Antworten ausgeführt, wäre das äquivalente ifStilkonstrukt:

if test -e FILENAME; then echo Yes; fi

oder alternativ:

if test -e FILENAME
then
    echo Yes
fi

Für diese Zwecke [und testsind gleichwertig, außer dass [eine Kündigung erforderlich ist ].

ein CVn
quelle
4

Um diese Art von Frage zu beantworten, gibt es mehrere Möglichkeiten, und hier ist eine andere: Verwenden Sie den findBefehl mit -execFlag. Der Pfad zur Datei kann in zwei Teile aufgeteilt werden, find /etcdie das Verzeichnis -name FILENAMEfestlegen und den Dateinamen angeben (duh!). -maxdepthhalten findmit Arbeit /etcnur Verzeichnis und senkt sich nicht in Unterverzeichnisse

adminx@L455D:~$ find /etc -maxdepth 1  -name passwd -exec printf "YES\n" \;
YES
adminx@L455D:~$ find /etc -maxdepth 1  -name passwd1 -exec printf "YES\n" \;
adminx@L455D:~$ 

Ein anderer Weg über stat:

adminx@L455D:~$ stat /etc/passwd1 &>/dev/null && echo YES
adminx@L455D:~$ stat /etc/passwd &>/dev/null && echo YES
YES

Und alternativ über Python:

>>> import os
>>> if os.stat('/etc/passwd'): 
...    print 'YES'
... 
YES
>>> if os.stat('/etc/passwd1'): 
...    print 'YES'
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '/etc/passwd1'

Oder eine kurze Befehlszeilenalternative:

 python -c "from os.path import exists; print 'Yes' if exists('/etc/fstab') else '' "
Sergiy Kolodyazhnyy
quelle