Η Bash δεν έχει την έννοια των Boolean τιμών (λογικών τιμών). Υπάρχουν συμβολοσειρές και αριθμοί, καθώς και πίνακες συμβολοσειρών ή αριθμών. Πώς, λοιπόν, χειρίζονται οι εντολές συνθήκης το αληθές και το ψευδές;
Οι εντολές παράγουν μια κατάσταση εξόδου όταν τερματίζουν. Η κατάσταση εξόδου είναι ένας ακέραιος μεταξύ 0 και 255, συμπεριλαμβανομένων. Η Bash θεωρεί πως μια κατάσταση εξόδου μηδέν αντιπροσωπεύει επιτυχία. Οποιαδήποτε άλλη κατάσταση εξόδου αντιπροσωπεύει αποτυχία.
Αυτό ισχύει για όλες τις εντολές, συμπεριλαμβανομένων των ενσωματωμένων εντολών της Bash, των λέξεων-κλειδιών και των συναρτήσεων.
Η βασική σύνταξη της εντολής if είναι
if CONDITIONAL_COMMANDS; then TRUE_COMMANDS; else FALSE_COMMANDS; fi
Ξεκινά με if, οι εντολές συνθήκης χωρίζονται από τις εντολές "επιτυχίας" με το then, και τερματίζεται με το fi.
Ο κλάδος else είναι προαιρετικός.
Οι CONDITIONAL_COMMANDS μπορούν να είναι μία μόνο εντολή ή μια λίστα εντολών.
Οι CONDITIONAL_COMMANDS εκτελούνται και
Διαδοχικοί κλάδοι μπορούν να δοθούν με το elif
if CONDITIONAL_COMMANDS
then TRUE_COMMANDS
elif CONDITIONAL_COMMANDS_2
then TRUE_COMMANDS_2
# more elif branches ...
else FALSE_COMMANDS
fi
Πρέπει να υπάρχει ένα ; ή μια αλλαγή γραμμής πριν από τις λέξεις then, elif, else και fi.
Για να το τονίσουμε: αυτό που ελέγχει τη ροή είναι η κατάσταση εξόδου των εντολών συνθήκης.
Για παράδειγμα, το grep επιστρέφει 0 αν βρεθεί αντιστοιχία και 1 αν δεν βρεθεί.
Η επιλογή -q καταστέλλει την έξοδο, παράγοντας μόνο την κατάσταση εξόδου.
if grep -q "my pattern" my_file; then echo "the pattern is found in the file"; fi
Δεν υπάρχει ειδική σύνταξη γύρω από τις CONDITIONAL_COMMANDS.
Ίσως έχεις συνηθίσει να βλέπεις εντολές if που μοιάζουν κάπως έτσι:
if [ "$password" = "secure" ]; then
echo "Welcome!"
fi
Το [ δεν είναι ειδική σύνταξη.
Είναι μια εντολή που αξιολογεί την έκφραση συνθήκης και τερματίζει με κατάσταση επιτυχίας/αποτυχίας.
Όπως σε όλες τις εντολές, τα κενά διαστήματα ανάμεσα σε αυτήν και τα ορίσματά της είναι απαραίτητα.
Το [ είναι στην πραγματικότητα συνώνυμο της εντολής test.
Είναι ακριβώς τα ίδια, με τη διαφορά ότι το τελευταίο όρισμα του [ πρέπει να είναι ].
Μέσα στα [ και ] γράφεις μια έκφραση συνθήκης.
Μερικές τυπικές εκφράσεις συνθήκης είναι οι εξής:
[ -f "$filename" ] # file operations
[ "$string1" = "$string2" ] # string comparisons
[ "$num1" -eq "$num2" ] # arithmetic comparisons
Υπάρχουν πολλές ακόμη διαθέσιμες λειτουργίες, οι οποίες αναφέρονται στην ενότητα Εκφράσεις συνθήκης της Bash του εγχειριδίου.
Στα παραπάνω παραδείγματα, πρόσεξε ότι όλες οι μεταβλητές είναι μέσα σε εισαγωγικά.
Οι εντολές test και [ είναι απλές εντολές, όπου τα ορίσματα υπόκεινται σε διαχωρισμό λέξεων και επέκταση ονομάτων αρχείων, όπως σε κάθε άλλη εντολή.
Αυτό αξίζει να επισημανθεί, γιατί οι εκφράσεις συνθήκης αξιολογούνται διαφορετικά ανάλογα με το πόσα ορίσματα δίνεις:
[ -z "$name" ]) ή ένα ! (που αντιστρέφει την κατάσταση της δοκιμής με 1 όρισμα)Μπορείς να πάρεις απροσδόκητα αποτελέσματα αν ξεχάσεις τα εισαγωγικά:
str=""
# this prints "empty"
if [ -n "$str" ]; then echo "not empty"; else echo "empty"; fi
# leaving the variable unquoted results in incorrect "not empty" output
if [ -n $str ]; then echo "not empty"; else echo "empty"; fi
Το κατασκεύασμα συνθήκης [[...]] δεν είναι εντολή, είναι λέξη-κλειδί.
Αυτό σημαίνει ότι, παρόλο που αντιμετωπίζεται όπως κάθε άλλη εντολή, έχει ειδικούς κανόνες ανάλυσης.
Αυτό που κάνει το [[ ξεχωριστό είναι ότι οι μεταβλητές που επεκτείνονται μέσα του δεν υπόκεινται σε διαχωρισμό λέξεων ή επέκταση ονομάτων αρχείων.
Έτσι, αυτή η εντολή συμπεριφέρεται όπως περιμένεις, ακόμη και χωρίς εισαγωγικά.
if [[ -n $str ]]; then echo "not empty"; else echo "empty"; fi
Το [[ υποστηρίζει όλες τις εκφράσεις συνθήκης που μπορούν να χειριστούν τα test και [.
Επιπλέον, το [[ παρέχει
=~,== και != να λειτουργούν ως τελεστές αντιστοίχισης μοτίβων glob,&& και || ως λογικούς τελεστές (ειδικός κανόνας ανάλυσης),< και > ως "γυμνούς" τελεστές σύγκρισης συμβολοσειρών (ειδικός κανόνας ανάλυσης: επειδή είναι σύμβολα ανακατεύθυνσης, στο [ πρέπει να τα κάνεις escape).Επικρατεί ευρέως η άποψη ότι αυτά τα ειδικά χαρακτηριστικά προσφέρουν τόσα πολλά οφέλη, ώστε το [[ να πρέπει να χρησιμοποιείται αποκλειστικά.
(Για παράδειγμα, ο Google Shell Style Guide.)
Το case είναι μια ακόμη εντολή ροής ελέγχου.
Μοιάζει με μια εντολή "switch" σε άλλες γλώσσες.
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
Το WORD αντιστοιχίζεται με κάθε PATTERN. Όταν κάποιο ταιριάζει, εκτελούνται οι COMMANDS.
read -p "Guess the secret word: " word
case "$word" in
secret) echo "Yes, you guessed it!" ;;
??????) echo "That's the right number of letters." ;;
s*) echo "You guessed the first letter." ;;
*) echo "Not even close! Try again." ;;
esac
Κάθε κλάδος COMMANDS πρέπει να τελειώνει με δύο ;, δηλαδή ;;.