Στο προηγούμενο μάθημα μιλήσαμε για τον τρόπο δομής ενός bash script, κατανοήσαμε τον τρόπο που αποθηκεύεται μια μεταβλητή και πως να την καλούμε καθώς και πως να τυπώνουμε μηνύματα στο τερματικό. Στο παρόν μάθημα θα ελέγχουμε τη ροή ενός προγράμματος μαθαίνοντας τις βασικές λειτουργίες μιας if συνθήκης και θα δώσουμε μια ευελιξία στο πρόγραμμα μας.
Ρωτήθηκα αν υπάρχει διαφορά μεταξύ προγράμματος και scripting, η ουσία είναι η ίδια. το script ειναι ένα πρόγραμμα το οποίο το ονομάζουμε script λόγω του μικρού του μεγέθους και επιπλέον του γεγονότος ότι είναι διερμηνευόμενο και όχι μεταγλωττισμένο.
Ifthenelse script
Πριν ξεκινήσουμε
Ας δούμε τη μορφή ενός if statement στο bash.
if [[ η συνθήκη μου ]]; then εντολές else άλλες εντολές fi
Σημαντικότατο είναι τα κενά μεταξύ των [[
και των συνθηκών ]]
, δηλαδή if [[ εδωγραφουμε ]] δεν τα κολλάμε γιατί θα έχουμε λάθος.
Αξίζει να σημειωθεί ότι και με μονές αγκύλες ισχύει το if αλλά σε μεταγενέστερες εκδόσεις του bash, έχουμε πιο σύνθετες εκφράσεις και για αυτό η εισαγωγή των διπλών αγκυλών. Το γεγονός ότι μπορεί να έχετε μήνυμα λάθους με τις διπλές αγκύλες ενώ η έκφραση είναι σωστή, σημαίνει ότι απλά το αρχείο μας δεν είναι εκτελέσιμο ή το τρέχουμε με sh αντί για bash.
ifthenelse και μορφές δεδομένων
Ας δούμε το σημερινό πρόγραμμα το οποίο θα ονομάσουμε ifthenelse.sh
#!/bin/bash # Έλεγχος ροής και control operators read -rp "Δώσε έναν αριθμό : " number if [[ $number -eq 0 ]]; then echo "Έδωσες τον αριθμό 0" else echo "Έδωσες το $number" fi
Το ανωτέρω πρόγραμμα, διαβάζει έναν αριθμό μέσω της read όπου αυτός με τη σειρά του αποθηκεύεται στη μεταβλητή number. Ως εδώ γνωστά. Στη συνέχεια όμως επιλέγουμε να παραλλάξουμε τη συμπεριφορά του προγράμματος, ανάλογα με τα δεδομένα που εισάγαμε.
Εδώ αξίζει να αναφερθούμε στις μορφές δεδομένων που εισάγονται στο bash. Αυτές μπορεί να είναι είτε αριθμητικές, είτε σε μορφή συμβολοσειράς (string).
Στην παρούσα μορφή του προγράμματος μας χρησιμοποιούμε το -eq για να συγκρίνουμε το αριθμητικό δεδομένο μας με το μηδέν (0). Αν δίναμε string θα παίρναμε μήνυμα λάθους.
Πιο συγκεκριμένα οι operators με τους οποίους κάνουμε σύγκριση αριθμητικά δεδομένα είναι
- -lt μικρότερο
- -gt μεγαλύτερο
- -le μικρότερο ή ίσο
- -ge μεγαλύτερο ή ίσο
- -eq ίσο
- -ne όχι ίσο
Αν όμως θέλαμε να εξετάσουμε την ομοιότητα της μεταβλητής με ένα string θα γράφαμε
if [[ $number == "teststring" ]];
ifthenelse με pipe || (και)
Aς κάνουμε μια μικρή αλλαγή στο πρόγραμμα μας
#!/bin/bash # Έλεγχος ροής και control operators read -rp "Δώσε έναν αριθμό : " number if [[ $number -eq 0 ]] || [[ $number -eq 3 ]]; then echo "Έδωσες τον αριθμό 0 ή τον αριθμό 3" else echo "Έδωσες το $number" fi
Εδώ παρατηρούμε την εισαγωγή ενός διπλού pipe || που χρησιμεύει ως έκφραση της συνθήκης
Συνθήκη 1 || (ή) Συνθήκη 2
Αυτή η συνθήκη θα ικανοποιηθεί αν ισχύει ή το ένα ή το άλλο από τις συνθήκες που περικλείονται στις αγκύλες.
Αντιστοίχως το διπλό ampersand && χρησιμεύει ως έκφραση της συνθήκης
Συνθήκη 1 && (και) Συνθήκη 2
Αυτή η συνθήκη θα ικανοποιηθεί αν ισχύει ΚΑΙ το ένα ΚΑΙ το άλλο από τις συνθήκες που περικλείονται στις αγκύλες.
ifthenelse συνδυαστικές συνθήκες
Ας πάμε ένα βήμα παρακάτω
#!/bin/bash # Έλεγχος ροής και control operators read -rp "Δώσε έναν αριθμό : " number if [[ $number -eq 0 ]] || [[ $number -eq 3 ]] && [[ $number == "test" ]]; then echo "Έδωσες τον αριθμό 0 ή τον αριθμό 3 ή τη λέξη 'test'" else echo "Έδωσες το $number" fi
Όπως παρατηρούμε έχουμε μια σύνθετη συνθήκη, που έχει ένα ή και ένα και. Για να ισχύσει το if, πρέπει να ισχύσει η ΜΙΑ ΜΟΝΟ από τις 2 πρώτες συνθήκες ΚΑΙ ΑΠΑΡΑΙΤΗΤΑ η 3η συνθήκη για να μην ενεργοποιηθεί το else.
Όμως στη μορφή μου είναι γραμμένο το παρόν πρόγραμμα αυτή η συνθήκη δε θα ισχύσει ΠΟΤΕ. Αυτό γιατί δεν μπορούμε ταυτόχρονα να έχουμε 2 τιμές στη μεταβλητή number.
Ακολουθεί ένας διάλογος προγραμματιστικής λογικής και καθημερινής τρέλας
θα πάω για μπάλα ΑΝ : δε βρέχει ΚΑΙ έρθουν με πάρουν με αμάξι
αν βρέχει και έρθουν να με πάρουν με αμάξι δε θα πάω
αν δε βρέχει και δεν έρθουν να με πάρουν πάλι δε θα πάω
ifthenelse συνθήκη elif
Προχωρούμε σε μια πιο σύνθετη μορφή του προγράμματος μας
#!/bin/bash # Έλεγχος ροής και control operators read -rp "Δώσε έναν αριθμό : " number if [[ $number -eq 0 ]]; then echo "Έδωσες τον αριθμό 0" else if [[ $number -gt 10 ]]; then echo "Έδωσες το $number που είναι μεγαλύτερο του 10" elif [[ $number -eq 10 ]]; then echo "Έδωσες το 10" else echo "Έδωσες το $number που είναι μικρότερο του 10" fi fi
Στον κώδικα που γράψαμε παρατηρούμε ότι όχι μόνο ελέγχουμε ανάλογα με τον αριθμό που θα μας δοθεί τι θα τυπώσουμε, επιπλέον εισάγαμε και τον όρο elif που μας διευκολύνει σημαντικά στη συγγραφή.
Τι είναι όμως το elif
Παρατηρούμε ότι μέσα σε μια συνθήκη if μπορούμε να έχουμε πολλές διαφορετικές συνθήκες. Με την εισαγωγή κάθε elif στην ουσία προσθέτουμε ακόμα μια if συνθήκη χωρίς να χρειάζεται να ξαναγράφουμε την if όπως αυτή διατυπώθηκε στην αρχή του άρθρου.
Με απλά λόγια οι δύο μορφές κώδικα που ακολουθούν παράγουν ΑΚΡΙΒΩΣ το ίδιο αποτέλεσμα
Εκδοχή 1
if [[ συνθήκη 1 ]]; then εντολές if [[ συνθήκη 2 ]]; then άλλες εντολές fi else και άλλες εντολές fi
Εκδοχή 2
if [[ συνθήκη 1 ]]; then εντολές elif [[ συνθήκη 2 ]]; then άλλες εντολές else και άλλες εντολές fi
Τι μάθαμε;
Στο παρόν άρθρο, είδαμε πως μπορούμε να ελέγχουμε τη ροή ενός προγράμματος μαθαίνοντας τις βασικές λειτουργίες μιας if συνθήκης. Επίσης είδαμε πως μπορούμε να την εμπλουτίσουμε με τους operators AND και OR και τέλος κάναμε τον κώδικα μας πιο όμορφο με τη χρήση της elif.
Στο επόμενο μάθημα θα δούμε πως μπορούμε να χρησιμοποιούμε βρόγχους για την επίτευξη ποιον σύνθετων διαδικασιών
Όπως πάντα σε κάθε σειρά μαθημάτων, θα βρείτε τους κώδικες των προγραμμάτων στο github του Cerebrux στο αποθετήριο Bash-Lessons.
Όλα τα νέα αλλά και παλιότερα μαθήματα θα τα βρείτε στο λήμμα «μαθήματα shell scripting«
Πω ατάκες στυλ δώσε έναν αριθμό μου ξύπνησαν μνήμες από Turbo Pascal scriptάκια που κάναμε στο σχολείο! :P