Πρώτο commit
Αυτό το commit περιλαμβάνεται σε:
commit
8ec8e9bee2
451 αρχεία άλλαξαν με 46736 προσθήκες και 0 διαγραφές
197
content/articles/29/05_bash.md
Κανονικό αρχείο
197
content/articles/29/05_bash.md
Κανονικό αρχείο
|
@ -0,0 +1,197 @@
|
|||
+++
|
||||
title = 'Απλός χειρισμός Bash'
|
||||
date = '2000-09-01T00:00:00Z'
|
||||
description = ''
|
||||
author = 'Μιχάλης Καμπριάνης(mailto:kabrianis@hellug.gr)'
|
||||
issue = ['Magaz 29']
|
||||
issue_weight = 5
|
||||
+++
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
*Το standard shell του Linux είναι το bash, γι αυτό, ας μάθουμε μερικά πράγματα για αυτό.*
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Το Bash είναι ένα shell που χρησιμοποιείται ως standard στο Linux και υπάρχει διαθέσιμο και σαν πηγαίος κώδικας για να προστεθεί σε οποιoδήποτε Unix θέλετε.
|
||||
Είναι ένα POSIX-compliant shell και βασικά πρόκειται για μια μετεξέλιξη του shell (sh) συνδυάζοντας τα καλύτερα στοιχεία των C-shell (csh) και Korn-shel (ksh).\
|
||||
Το bash υποστηρίζει command-line editing, substitution, filename completion, προχωρημένες δυνατότητες scripting κλπ. Το bash υποστηρίζει βέβαια και
|
||||
wildcharacters ή χαρακτήρες-μπαλαντέρ (? για αντικατάσταση ενός χαρακτήρα και \* για αντικατάσταση απεριόριστων χαρακτήρων, `[ ]`
|
||||
για καθορισμό εύρους τιμών κλπ. Σε κάθε περίπτωση, αυτό το κείμενο δεν μπορεί παρά να κάνει μία απλή εισαγωγή, και για περισσότερες πληροφορίες που θα οδηγούσαν
|
||||
στην πλήρη εκμετάλλευση των δυνατοτήτων του bash, ο αναγνώστης πρέπει να διαβάσει το manual του bash (man bash).
|
||||
|
||||
**1. Μεταβλητές**
|
||||
----------------------------------------
|
||||
|
||||
**2. Ανακατεύθυνση**
|
||||
-------------------------------------------
|
||||
|
||||
**3. Έξοδος λογικής έκφρασης: test**
|
||||
-----------------------------------------------------------
|
||||
|
||||
**4. Έλεγχοι ροής**
|
||||
------------------------------------------
|
||||
|
||||
**5. Επαναληπτικοί βρόγχοι**
|
||||
---------------------------------------------------
|
||||
|
||||
|
||||
### [1. Μεταβλητές]{#s1}
|
||||
|
||||
Οι μεταβλητές (βασικό στοιχείο σε κάθε πρόγραμμα) στο bash δεν είναι προκαθορισμένου τύπου, μπορεί δηλαδή η ίδια μεταβλητή να έχει αριθμητική τιμή, ή τιμή
|
||||
κειμένου (string) κλπ χωρίς να το προδηλώσουμε πουθενά (αν και για το bash όλες οι μεταβλητές είναι strings, με την χρήση της eval μπορούμε να κάνουμε και
|
||||
αριθμητικές πράξεις αν τα strings αποτελούνται μόνο από αριθμούς). Οι μεταβλητές ορίζονται με απλή τοποθέτηση (assignment, π.χ. var=1) και προσπελαύνονται
|
||||
βάζοντας μπροστά από το όνομά τους το σύμβολο \$. Αν η τιμή μίας μεταβλητής εσωκλείεται σε διπλά εισαγωγικά \"\", τότε το bash αγνοεί οποιαδήποτε κενά
|
||||
βρίσκονται εκεί. Αν δεν τα αγνοούσε, η τιμή της μεταβλητής θα ήταν οτιδήποτε υπάρχει μέχρι το πρώτο κενό. Ότι ήταν μετά το κενό θα θεωρούνταν ως τιμή της
|
||||
δεύτερης μεταβλητής, κάτι το οποίο έχει ιδιαίτερο νόημα για παραμέτρους που δίνονται από την γραμμή εντολών κατά την κλήση του προγράμματος. Αν εσωκλείεται σε
|
||||
ανάποδα μονά εισαγωγικά \`, τότε εννοείται ότι πρόκειται περί εντολής, η οποία θα εκτελεστεί και το αποτέλεσμα της εντολής θα αποτελεί την τιμή της μεταβλητής.
|
||||
|
||||
Το bash χρησιμοποιεί κάποιες προκαθορισμένες μεταβλητές για τα διάφορα \"προγραμματάκια\" που μπορούμε να φτιάξουμε. Αυτές είναι οι:
|
||||
|
||||
- \$\# Ο αριθμός των παραμέτρων που δώσαμε στην γραμμή εντολών.
|
||||
- \$0 Η πρώτη λέξη της κληθείσας εντολής (πρακτικά δηλαδή το όνομα του προγράμματος).
|
||||
- \$1 - \$N Οι παράμετροι που δώσαμε στην γραμμή εντολών (όπου \$1 η πρώτη παράμετρος, και N ίσο με το \$\#).
|
||||
- \$@ Φυλάσσει το σύνολο των παραμέτρων της γραμμής εντολών (δηλαδή από \$1 μέχρι \$N όπως ακριβώς τις γράψαμε.) σε μορφή πίνακα (array).
|
||||
- \$\* Φυλάσσει το σύνολο των παραμέτρων της γραμμής εντολών (δηλαδή από \$1 μέχρι \$N όπως ακριβώς τις γράψαμε) σε μία μεταβλητή (μία και μόνη, τύπου
|
||||
string).
|
||||
- \$? Σε αυτή τη μεταβλητή φυλάσσεται το αποτέλεσμα εξόδου της προηγούμενης εντολής.
|
||||
|
||||
|
||||
### [2. Ανακατεύθυνση]{#s2}
|
||||
|
||||
Το bash υποστηρίζει όπως θα ήταν ίσως αναμενόμενο, ανακατεύθυνση των τριών βασικών file descriptors, δηλαδή των standard input, standard output και standard
|
||||
error (αντίστοιχα 0, 1 και 2). Η ανακατεύθυνση της εισόδου γίνεται με το σύμβολο \<, και η ανακατεύθυνση εξόδου (και εξόδου λάθους) με το σύμβολο \> γράφοντας
|
||||
και τον αριθμό του file descriptor. Δηλαδή η έκφραση command 1\> output θα ανακατευθύνει την κανονική έξοδο στο αρχείο output (και είναι ισοδύναμη με την
|
||||
command \> output) ενώ η έκφραση command 2\> error θα ανακατευθύνει την έξοδο λάθους στο αρχείο error. Για να ανακατευθύνουμε και την κανονική έξοδο, αλλά και
|
||||
την έξοδο λάθους σε ένα αρχείο, μπορούμε να χρησιμοποιήσουμε οποιαδήποτε από τις ακόλουθες εκφράσεις:
|
||||
`command &> out, command >& out, command 2>&1 out`
|
||||
|
||||
Τέλος, το bash υποστηρίζει και piping, να ανακατευθύνει δηλαδή την έξοδο μίας εντολής, στην είσοδο μίας άλλης εντολής, με το σύμβολο \|.
|
||||
|
||||
|
||||
### [3. Έξοδος λογικής έκφρασης: test]{#s3}
|
||||
|
||||
Όποτε θέλουμε να ελέγξουμε το αποτέλεσμα μίας λογικής ή αριθμητικής έκφρασης χρησιμοποιούμε τη συνάρτηση test. Η συνάρτηση test επιστρέφει τιμή \"αληθής\" ή
|
||||
\"ψευδής\" ανάλογα με το αληθές ή ψευδές της λογικής (ή και αριθμητικής) έκφρασης που ελέγχεται. H συνάρτηση test μπορεί να γραφεί και ώς `[ έλεγχος ]` . Η
|
||||
έκφραση μπορεί να έχει ένα μόνο στοιχείο και έναν τελεστή (ο οποίος έτσι ονομάζεται unary operator) ή μπορεί να έχει δύο στοιχεία και έναν τελεστή ο οποίος
|
||||
ονομάζεται binary operator. Πιο πολλές πληροφορίες από το manual page της συνάρτησης test το οποίο μπορείτε να δείτε γράφοντας man test
|
||||
|
||||
Οι πιο συνηθισμένοι τελεστές:
|
||||
|
||||
- `test [ 1 -eq 2 ]`\
|
||||
Η ανωτέρω έκφραση είναι ψευδής γιατί ο (αριθμητικός) τελεστής -eq σημαίνει ισότητα (equal). Άλλοι αριθμητικοί τελεστές είναι οι:
|
||||
1. -gt ο αριθμός αριστερά είναι μεγαλύτερος από τον αριθμό δεξιά (greater than).
|
||||
2. -lt ο αριθμός δεξιά είναι μικρότερος από τον αριθμό αριστερά (less than).
|
||||
3. -ne οι δύο αριθμοί δεν είναι ίσοι (not equal).
|
||||
4. -ge ο αριθμός αριστερά είναι μεγαλύτερος ή ίσος από τον αριθμό δεξιά (greater or equal).
|
||||
5. -le ο αριθμός αριστερά είναι μικρότερος ή ίσος από τον αριθμό δεξιά (less or equal).
|
||||
- `test [ like = likme ]`\
|
||||
Η ανωτέρω έκφραση είναι ψευδής γιατί ο (λογικός) τελεστής = σημαίνει ότι τα δύο strings που συγκρίνουμε είναι ίσα (ίδια). Άλλοι λογικοί τελεστές σχετικοί με
|
||||
strings είναι οι:
|
||||
1. != ο οποίος προφανώς επιστρέφει \"αληθές\" όταν τα δύο strings που συγκρίνουμε είναι ανόμοια.
|
||||
2. -z ο οποίος είναι unary operator (συντάσσεται δηλαδή ως εξής: `test [ -z string ]`) επιστρέφει \"αληθές\" αν το μήκος του string είναι μηδενικό.
|
||||
3. -n που είναι και αυτός unary operator (συντάσσεται δηλαδή ως εξής: `test [ -n string ]`) επιστρέφει \"αληθές\" αν το μήκος του string δεν είναι
|
||||
μηδενικό.
|
||||
- `test [ -e filename ]`\
|
||||
Η ανωτέρω έκφραση βγαίνει αληθής όταν το αρχείο με όνομα filename υπάρχει. Άλλοι τελεστές ελέγχου της κατάστασης ενός αρχείου είναι οι εξής (όλοι όσοι
|
||||
αναφέρονται εδώ είναι unary operators):
|
||||
1. -b αν το αρχείο υπάρχει και είναι block device
|
||||
2. -c αν το αρχείο υπάρχει και είναι character device
|
||||
3. -d αν το αρχείο υπάρχει και είναι directory
|
||||
4. -f αν το αρχείο υπάρχει και είναι κανονικό αρχείο
|
||||
5. -r αν το αρχείο υπάρχει και μπορεί να διαβαστεί
|
||||
6. -s αν το αρχείο υπάρχει και το μέγεθος του δεν είναι μηδέν
|
||||
7. -w αν το αρχείο υπάρχει και μπορεί να γραφτεί
|
||||
8. -x αν το αρχείο υπάρχει και μπορεί να εκτελεστεί
|
||||
|
||||
|
||||
### [4. Έλεγχοι ροής]{#s4}
|
||||
|
||||
- if - then - else
|
||||
|
||||
Ένας τρόπος και ο πιο συνηθισμένος ελέγχου ροής ενός προγράμματος είναι ο έλεγχος if-then-else όπου ελέγχουμε το αποτέλεσμα μίας λογικής έκφρασης και
|
||||
ανάλογα με αυτό το αποτέλεσμα καθορίζουμε τι θα κάνει το πρόγραμμα. Προφανώς ο έλεγχος χρησιμοποιεί το αποτέλεσμα της συνάρτησης test για να καθορίσει την
|
||||
ροή. Για παράδειγμα
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
if [ $i -eq 3 ]; then
|
||||
echo 'Number is 3';
|
||||
elif [ $i -eq 2 ]; then
|
||||
echo 'Number is 2';
|
||||
else echo 'Number is neither 3 nor 2';
|
||||
fi
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
όπου είναι προφανές ότι κάπου στο πρόγραμμά μας έχουμε δώσει τιμή στην παράμετρο \$i. Μπορούμε να έχουμε όσα elif θέλουμε, αρκεί στο τέλος να υπάρχει και
|
||||
ένα else. Αν δεν υπάρχει κανέναν elif δεν είναι υποχρεωτικό και το else, είναι όμως σε κάθε περίπτωση υποχρεωτικό το fi.
|
||||
|
||||
- select
|
||||
|
||||
Η συνάρτηση select δουλεύει (και συντάσσεται) όπως η if αλλά δίνει τη δυνατότητα να δημιουργήσουμε menu. Για παράδειγμα
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
select i in a.txt b.txt c.txt; do
|
||||
cat $i;
|
||||
done
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Το ανωτέρω παράδειγμα παρουσιάζει στον χρήστη ένα menu με τρεις επιλογές και ανάλογα με την επιλογή του χρήστη, του εμφανίζει το αντίστοιχο αρχείο στην
|
||||
οθόνη.
|
||||
|
||||
- case
|
||||
|
||||
Η συνάρτηση case τέλος, προσομοιάζει στην αντίστοιχη συνάρτηση της C και σαν σύνταξη, αλλά και σαν αποτέλεσμα, και συγκεκριμένα εκτελεί προκαθορισμένες
|
||||
εντολές για προκαθορισμένες τιμές μίας μεταβλητής, έχοντας ταυτόχρονα και μία γενική περίπτωση που δεν εμπίπτει στις υπόλοιπες. Για παράδειγμα
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
case $i in
|
||||
1 | 3 | 5 | 7 | 9) echo -n "Odd one-digit number";;
|
||||
0 | 2 | 4 | 6 | 8) echo -n "Even one-digit number";;
|
||||
*) echo -n "It definitely is not a one-digit nummber";;
|
||||
esac
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Το ανωτέρω παράδειγμα ελέχει την μεταβλητή \$i που υποτίθεται ότι κάπου πιο πριν την έχουμε δώσει, και μας απαντάει αν είναι μονός ή ζυγός μονοψήφιος
|
||||
αριθμός, ή όχι.
|
||||
|
||||
|
||||
### [5. Επαναληπτικοί βρόγχοι]{#s5}
|
||||
|
||||
- for - do
|
||||
|
||||
Ο βρόγχος for - do είναι ο πιο συνηθισμένος σε όλες τις γλώσσες προγραμματισμού. Η χρήση του είναι απλούστατη ειδικά στο bash όπου \\textbf{δεν μπορούμε να
|
||||
ορίσουμε πεδίο τιμών, αντ\' αυτού είμαστε υποχρεωμένοι να ορίζουμε τις τιμές μία μία, ακόμα και αν αυτές είναι κατά κάποια έννοια συνεχόμενες. Ένα
|
||||
παράδειγμα είναι το απλούστατο:
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
for i in 1 3 5 ; do
|
||||
echo $i;
|
||||
done
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Το πεδίο τιμών της μεταβλητής \$i δεν αποτελείται υποχρεωτικά από αριθμούς αλλά μπορεί να είναι και λέξεις ή γράμματα, ή ακόμα και wildcharacters (\* και ?)
|
||||
κάνοντας έτσι αυτό τον βρόγχο ένα πανίσχυρο εργαλείο.
|
||||
|
||||
- while - do Η συνάρτηση while εκτελεί κάποιες εντολές όσο μία λογική έκφραση είναι αληθής. Το κλασικότερο παράδειγμα είναι η δημιουργία ενός επαναληπτικού
|
||||
βρόγχου, ως εξής:
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
while [ $i -lt 10 ]; do
|
||||
read i;
|
||||
echo $i;
|
||||
done
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Προφανώς το παράδειγμα αυτό θα μας εμφανίζει συνέχεια ότι του γράφουμε μέχρι να δώσουμε ένα αριθμό μεγαλύτερο (ή ίσο) του 10. Προσοχή χρειάζεται εδώ, γιατί
|
||||
στο πρόγραμμά μας η μεταβλητή \$i πρέπει να έχει τιμή πριν κληθεί η while.
|
||||
|
Φόρτωση…
Προσθήκη πίνακα
Προσθήκη υπερσυνδέσμου
Παράθεση σε νέο ζήτημα