Διαδρομές
/
Bash
Bash
/
Ύλη
/
Συνθήκες
Συ

Συνθήκες σε Bash

{one: "1 άσκηση", other: "%{count} ασκήσεις"}

Σχετικά με την έννοια Συνθήκες

Αληθές και ψευδές στη Bash

Η Bash δεν έχει την έννοια των Boolean τιμών (λογικών τιμών). Υπάρχουν συμβολοσειρές και αριθμοί, καθώς και πίνακες συμβολοσειρών ή αριθμών. Πώς, λοιπόν, χειρίζονται οι εντολές συνθήκης το αληθές και το ψευδές;

Κατάσταση εξόδου

Οι εντολές παράγουν μια κατάσταση εξόδου όταν τερματίζουν. Η κατάσταση εξόδου είναι ένας ακέραιος μεταξύ 0 και 255, συμπεριλαμβανομένων. Η Bash θεωρεί πως μια κατάσταση εξόδου μηδέν αντιπροσωπεύει επιτυχία. Οποιαδήποτε άλλη κατάσταση εξόδου αντιπροσωπεύει αποτυχία.

Αυτό ισχύει για όλες τις εντολές, συμπεριλαμβανομένων των ενσωματωμένων εντολών της Bash, των λέξεων-κλειδιών και των συναρτήσεων.

Η εντολή "if"

Η βασική σύνταξη της εντολής if είναι

if CONDITIONAL_COMMANDS; then TRUE_COMMANDS; else FALSE_COMMANDS; fi

Ξεκινά με if, οι εντολές συνθήκης χωρίζονται από τις εντολές "επιτυχίας" με το then, και τερματίζεται με το fi. Ο κλάδος else είναι προαιρετικός.

Οι CONDITIONAL_COMMANDS μπορούν να είναι μία μόνο εντολή ή μια λίστα εντολών.

Οι CONDITIONAL_COMMANDS εκτελούνται και

  • αν η κατάσταση εξόδου είναι μηδέν (επιτυχία), τότε εκτελούνται οι TRUE_COMMANDS.
  • αν η κατάσταση εξόδου είναι μη μηδενική (αποτυχία), τότε εκτελούνται οι FALSE_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

Οι εντολές "[" και "test"

Δεν υπάρχει ειδική σύνταξη γύρω από τις 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 του εγχειριδίου.

Note

Στα παραπάνω παραδείγματα, πρόσεξε ότι όλες οι μεταβλητές είναι μέσα σε εισαγωγικά. Οι εντολές test και [ είναι απλές εντολές, όπου τα ορίσματα υπόκεινται σε διαχωρισμό λέξεων και επέκταση ονομάτων αρχείων, όπως σε κάθε άλλη εντολή.

Αυτό αξίζει να επισημανθεί, γιατί οι εκφράσεις συνθήκης αξιολογούνται διαφορετικά ανάλογα με το πόσα ορίσματα δίνεις:

  • 0 ορίσματα: η κατάσταση εξόδου είναι μη μηδενική (αποτυχία)
  • 1 όρισμα: η κατάσταση εξόδου είναι μηδέν (επιτυχία) αν το όρισμα δεν είναι κενό, μη μηδενική αν είναι κενό.
  • 2 ορίσματα: το πρώτο όρισμα πρέπει να είναι μοναδιαίος τελεστής (όπως [ -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"

Το 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 πρέπει να τελειώνει με δύο ;, δηλαδή ;;.

Note
  1. Υπάρχουν εναλλακτικές που παρέχουν λειτουργικότητα για εκτέλεση εντολών με πτώση και για συνέχιση της αντιστοίχισης μοτίβων. Δες το εγχειρίδιο για λεπτομέρειες.
  2. Θυμήσου ότι μιλήσαμε για μοτίβα στην ενότητα Επέκταση ονομάτων αρχείων της έννοιας της Παράθεσης.
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα