Shell-Skript: Wenn mehrere Bedingungen

7

Ich möchte ein Shell-Skript erstellen, das etwas wiedergibt, wenn 3 Verzeichnisse nicht vorhanden sind.

Hier ist der Code, den ich geschrieben habe: test.sh:

if [ ! -d "/home/unix/POSTagger2" ] || [! -d "/home/unix/POSTagger2/stanford-parser-full-2015-12-09"] || [! -d "/home/unix/POSTagger2/stanford-corenlp-full-2015-12-09"]; then
echo "Nope"
fi

Wenn ich es ausführe, erhalte ich folgende Fehlermeldung:

./test.sh: line 1: [!: command not found

Was ist falsch an meiner Syntax?

Henley Chiu
quelle
In der ersten Bedingung hatten Sie es richtig. Dasselbe in der zweiten Bedingung zu tun, wäre das erste, was ich getan hätte ...
glglgl
[ist kein Token, sondern ein Befehl (ein anderer Name für den Befehl test), der durch Leerzeichen getrennt werden muss. Ein ähnlicher Fall ist ]ein Befehlsparameter, der ebenfalls durch ein Leerzeichen getrennt werden muss.
Pabouk

Antworten:

15

Ihnen fehlen einige Leerzeichen, zum Beispiel [!muss [ !und "]muss " ]auf den korrigierten Code geachtet werden:

#!/bin/bash
if 
[ ! -d "/home/unix/POSTagger2" ] || 
[ ! -d "/home/unix/POSTagger2/stanford-parser-full-2015-12-09" ] || 
[ ! -d "/home/unix/POSTagger2/stanford-corenlp-full-2015-12-09" ] 
then
      echo "Nope"
fi

Ein anderer Weg für Ihren Code:

#!/bin/bash
for dir in "/home/unix/POSTagger2" "/home/unix/POSTagger2/stanford-parser-full-2015-12-09" "/home/unix/POSTagger2/stanford-corenlp-full-2015-12-09"; do
     if [ ! -d "$dir" ]; then echo nope ; break; fi 
done  
Luciano Andress Martini
quelle
9

Sie benötigen ein Leerzeichen zwischen [und, damit die !Dinge richtig funktionieren. Dies liegt daran, dass [es als Shell-eingebauter Befehl implementiert ist (es war sogar eine separate ausführbare Datei /usr/bin/[).

Sie können auch verwenden:

if [ ! -d "/home/unix/POSTagger2" -o ! -d "/home/unix/POSTagger2/stanford-parser-full-2015-12-09" -o ! -d "/home/unix/POSTagger2/stanford-corenlp-full-2015-12-09") ] ; then
    echo "Nope"
fi

Bash bietet eine Alternative [[, die als en expression implementiert ist. [[Anwendungen &&, ||etc. statt -a, -oda die Betreiber.

if [[ ! (-d "/home/unix/POSTagger2" && -d "/home/unix/POSTagger2/stanford-parser-full-2015-12-09" && -d "/home/unix/POSTagger2/stanford-corenlp-full-2015-12-09") ]] ; then
    echo yes
fi

Bearbeiten: Dank der Kommentare von @LucianoAndressMartini und @pabouk für wichtige Korrekturen meines Verständnisses.

Satya Mishra
quelle
1
Nein! Du liegst falsch. Wenn Sie versuchen, das Verzeichnis / usr / bin / [in einen anderen Ordner zu verschieben, funktioniert die bedingte Anweisung weiterhin einwandfrei, da es sich um eine integrierte Bash-Datei handelt. Diese ausführbare Datei wird nicht von Bash verwendet. Sie wird als Kompatibilitätsoption angeboten für einige alte Shell, so dass sie einen Bash-Code ohne Fehler ausführen können.
Luciano Andress Martini
3
Es ist ein eingebauter Befehl in Bash, aber die Tatsache, dass er sich wie jeder Befehl verhält und ein Leerzeichen benötigt, gilt weiterhin.
Ilkkachu
1
Ja, dieser Teil der Antwort gilt weiterhin. Es ist eine großartige Antwort, das einzig Falsche ist zu denken, dass "[" keine eingebaute Shell ist.
Luciano Andress Martini
1
Nun, ich habe etwas Neues gelernt! Ich habe meine Ansicht [seit 1999 anscheinend nie überarbeitet .
Satya Mishra
1
[[ist kein Befehl. Es ist ein Token und einige Sonderzeichen haben eine andere Bedeutung zwischen [[und ]]. Außerdem ist es nicht POSIX-konform und funktioniert nur in einigen Shells wie Bash oder Korn. Siehe zum Beispiel mywiki.wooledge.org/BashFAQ/031
pabouk