Logisches UND in einem Bash-Skript

10

Ich habe ein ifin meinem Bash-Skript, das überprüfen muss, ob JEDE der 2 Dateien vorhanden ist. Wenn sie nicht vorhanden sind, sollte es eine Echo-Übereinstimmung geben.

Code, den ich habe:

if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Aber das scheint aus irgendeinem Grund nicht zu funktionieren.

Ich bin zu 110% sicher, dass diese 2 Dateien nicht existieren. Ich bekomme keine Fehler, es geht einfach nicht in die if.

Ich bin neu im Bash-Scripting, daher bin ich mir nicht sicher, was falsch sein könnte.

Peppercat101
quelle
Ich glaube nicht, dass eine der Antworten tatsächlich die Frage anspricht. Was passiert, wenn Sie die Tests einzeln ausprobieren? Tun Sie [[ ! -f /etc/.../... ]]; echo $?für jeden.
jw013
Eine Warnung : [[ -f xxx ]]Gibt true zurück, wenn xxx vorhanden ist und eine reguläre Datei (oder ein Symlink zu einer regulären Datei) ist. Es wird false zurückgegeben, wenn es nicht existiert oder wenn es nicht erkennen kann, ob es existiert oder nicht oder ob es existiert, aber keine reguläre Datei (Verzeichnis, Pipe, Gerät, Socket ...) ist oder ob es sich um einen Symlink handelt zu einer Datei, die nicht existiert oder nicht erkennen kann, ob sie existiert oder nicht oder keine reguläre Datei ist ... [[ -e $file ]] || [[ -L $file ]]ist näher an einem Test für die Existenz. ls -d -- "$file" > /dev/null 2>&1ist noch näher. Und in der Regel führt diese Art von Test zu Rennbedingungen. Vielleicht gibt es einen anderen Weg.
Stéphane Chazelas

Antworten:

12

Wenn Sie entweder wollen OR, dann wollen Sie nicht AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • Dies stimmt überein, wenn eine oder beide Dateien fehlen.
  • Ihr Code wird nur gedruckt, matchwenn beide nicht vorhanden sind.

Aber du hast gesagt:

Ich bin zu 110% sicher, dass diese 2 Dateien nicht existieren. Ich bekomme keine Fehler, es wird nur nicht das if eingegeben.

Ihre Aussage widerspricht sich also. Mindestens eine dieser Dateien muss vorhanden sein, wenn Sie diesen Code ausführen.

Wenn Sie sehen möchten, wie Ihre ifAnweisung bewertet wird, führen Sie sie mit aus -x.

#!/bin/bash -x
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Dann sehen Sie die Ausführung.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 
Bahamat
quelle
Ich möchte, dass "match" wiedergegeben wird, wenn keine der Dateien vorhanden ist. Wenn eine vorhanden ist, wird keine Übereinstimmung gedruckt. Ich werde es mit -x versuchen
Peppercat101
In diesem Fall sollte Ihr Originalcode in Ordnung sein. Und tatsächlich funktioniert es bei mir.
Bahamat
3

Sollte das nicht so sein? A ist eine Datei oder B ist eine Datei, dann blabla.

if [[ -f /etc/benchmarking/code ]] || [[ -f /etc/benchmarking/code.class ]]; 
then  
  echo "match"
fi
Gänseblümchen
quelle
3

Dies kann auch für das funktionieren, was Sie versuchen zu tun. Einzelne Klammern werden heutzutage bei Bash nicht mehr häufig verwendet, dies ist jedoch immer noch eine Option. Die Verwendung von '-o' ist effektiv eine "ODER" -Operation und "!" negiert die Bedingung.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"
Schrägstrich
quelle
Verwenden Sie nie [in bash. Abgesehen davon sehe ich nicht, wie dies die Frage beantwortet.
jw013
[ ! -f ${var} -a ! -f {var}.class ] && echo "match"es sollte sein. Die Aufgabe war: Wenn sie (beide) nicht existieren, sollte es so sein echo match.
hschou
0

Ihr Code erfüllt Ihre Anforderungen: Er wird gedruckt, matchsofern keine der beiden Dateien gefunden werden kann.

Daher wird der Grund matchnicht an anderer Stelle gedruckt. Sie sollten bestätigen, dass der Codeblock erreicht ist. Dies können Sie tun, indem Sie ihn mit einigen Debug-Meldungen umgeben. Zum Beispiel so:

echo '@ About to enter if...fi block'
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
echo '@ Finished if...fi block'

Normalerweise bevorzuge ich das Debuggen von Nachrichten an stderr , um zu vermeiden, dass der Datenfluss zu stdout unterbrochen wird. Ich habe dies hier jedoch vermieden, weil Sie sagten, Sie seien Anfänger. Hier ist ein Beispiel, das zeigt, wie Sie in stdout schreiben können :

echo '@ About to enter if...fi block' >&2
Roaima
quelle