Οδηγός Bash για αρχαρίους

Machtelt Garrels

Xalasys.com


<tille wants no spam _at_ xalasys dot com>

Έκδοση 1.8  Ενημέρωση 20060315 

Πρώτη έκδοση Ελληνικής μετάφρασης Φεβρουάριος 2008


Περιεχόμενα

Εισαγωγή

1. Γιατί αυτός ο οδηγός;

2. Ποιός πρέπει να διαβάσει αυτό το βιβλίο;

3. Νέες εκδόσεις, μεταφράσεις και διαθεσιμότητα

4. Ιστορικό αναθεωρήσεων

5. Συνεισφορές

6. Ανάδραση

7. Πληροφορίες Copyright

8. Τι χρειάζεστε;

9. Συμβάσεις του κειμένου

10. Οργάνωση του κειμένου

1. Bash και σενάρια Bash

1.1. Κοινά προγράμματα φλοιού

1.2. Πλεονεκτήματα του Bash (Bourne Again SHell)

1.3. Eκτέλεση εντολών

1.4. Δομικά μέρη

1.5. Ανάπτυξη καλών σεναρίων

1.6. Περίληψη

1.7. Ασκήσεις

2. Συγγραφή και εκσφαλμάτωση σεναρίων

2.1. Δημιουργία και εκτέλεση ενός σεναρίου

2.2. Τα βασικά των σεναρίων

2.3. Εκσφαλμάτωση σεναρίων Bash

2.4. Περίληψη

2.5. Ασκήσεις

3. Το περιβάλλον Bash

3.1. Αρχεία ρύθμισης φλοιού

3.2. Μεταβλητές

3.3. Χαρακτήρες σε εισαγωγικά

3.4. Επέκταση φλοιού

3.5. Ψευδώνυμα

3.6. Άλλες επιλογές του Bash

3.7. Περίληψη

3.8. Ασκήσεις

4. Κανονικές εκφράσεις

4.1. Κανονικές εκφράσεις

4.2. Παραδείγματα με το grep

4.3. Ταύτιση προτύπων με το Bash

4.4. Περίληψη

4.5. Ασκήσεις

5. Ο συντάκτης ροής GNU sed

5.1. Εισγαωγή

5.2. Διαλογική σύνταξη

5.3. Μη-διαλογική σύνταξη

5.4. Περίληψη

5.5. Ασκήσεις

6. Η γλώσσα προγραμματισμού GNU awk

6.1. Εκκίνηση με την gawk

6.2. Το πρόγραμμα print

6.3. Μεταβλητές gawk

6.4. Περίληψη

6.5. Ασκήσεις

7. Δηλώσεις απόφασης

7.1. Εισαγωγή στο if

7.2. Προχωρημένη χρήση του if

7.3. Δηλώσεις case

7.4. Περίληψη

7.5. Ασκήσεις

8. Συγγραφή διαλογικών σεναρίων

8.1. Εμφάνιση μηνυμάτων χρήστη

8.2. Λήψη εισόδου χρήστη

8.3. Περίληψη

8.4. Ασκήσεις

9. Επαναληπτικές εργασίες

9.1. Ο βρόχος for

9.2. Ο βρόχος while

9.3. Ο βρόχος until

9.4. Ανακατεύθυνση Ε/Ε και βρόχοι

9.5. Break και continue

9.6. Δημιουργία menu με τη select

9.7. Η εντολή shift

9.8. Περίληψη

9.9. Ασκήσεις

10. Περισσότερα για μεταβλητές

10.1. Τύποι μεταβλητών

10.2. Πίνακες μεταβλητών

10.3. Λειτουργίες σε μεταβλητές

10.4. Περίληψη

10.5. Ασκήσεις

11. Συναρτήσεις

11.1. Εισαγωγή

11.2. Παραδείγματα συναρτήσεων σε σενάρια

11.3. Περίληψη

11.4. Ασκήσεις

12. Λήψη σημάτων

12.1. Σήματα

12.2. Παγίδες

12.3. Περίληψη

12.4. Ασκήσεις

A. Χαρακτηριστικά φλοιών

A.1. Κοινά χαρακτηριστικά

A.2. Διαφορετικά χαρακτηριστικά

B. GNU Free Documentation License

B.1. Preamble

B.2. Applicability and definitions

B.3. Verbatim copying

B.4. Copying in quantity

B.5. Modifications

B.6. Combining documents

B.7. Collections of documents

B.8. Aggregation with independent works

B.9. Translation

B.10. Termination

B.11. Future revisions of this license

B.12. How to use this License for your documents

Ευρετήριο

Λίστα πινάκων

1. Τυπογραφικές και χρηστικές συμβάσεις

1-1. Επισκόπηση  προγραμματιστικών όρων

2-1. Επισκόπηση επιλογών εκσφαλμάτωσης

3-1. Δεσμευμένες μεταβλητές φλοιού Bourne

3-2. Δεσμευμένες μεταβλητές φλοιού Bash

3-3. Ειδικές μεταβλητές Bash 

3-4. Αριθμητικοί τελεστές

4-1. Τελεστές κανονικών εκφράσεων

5-1. Εντολές σύνταξης sed

5-2. Επιλογές sed

6-1. Χαρακτήρες μορφοποίησης gawk

7-1. Βασικές εκφράσεις

7-2. Συνδυασμοί εκφράσεων

8-1. Ακολουθίες διαφυγής της echo

8-2. Επιλογές read 

10-1. Επιλογές declare

12-1. Σήματα ελέγχου στο Bash

12-2. Συνηθισμένα σήματα τερματισμού

A-1. Κοινά χαρακτηριστικά φλοιών

A-2. Διαφορετικά χαρακτηριστικά φλοιών

Λίστα εικόνων

1. Bash Guide for Beginners : εξώφυλλο

2-1. script1.sh

3-1. Διαφορετικές προτροπές για διαφορετικούς χρήστες

6-1. Πεδία στην awk

7-1. Έλεγχος ορισμάτων γραμμής εντολών με if

7-2. Παράδειγμα χρήσης λογικών τελεστών


Εισαγωγή

1. Γιατί αυτός ο οδηγός;

Ο πρωταρχικός λόγος για την συγγραφή αυτού του οδηγού είναι ότι πολλοί αναγνώστες νοιώθουν ότι το υπάρχον HOWTO είναι πολυ σύντομο και ατελές, ενώ ο οδηγός Bash Scripting είναι περισσότερο έργο αναφοράς.  Δεν υπάρχει τίποτε μεταξύ αυτών των δύο άκρων. Επίσης έγραψα αυτό τον οδηγό με τη γενική αρχή ότι δεν υπάρχουν τόσα δωρεάν βασικά μαθήματα διαθέσιμα, όσα θα έπρεπε να υπάρχουν.  

Πρόκειται για ένα πρακτικό οδηγό, ο οποίος, ενώ δεν είναι υπερβολικά σοβαρός, προσπαθεί να δώσει πραγματικά, καθημερινά παραδείγματα αντί για θεωρητικά. Εν μέρει το έγραψα αυτό επειδή δεν ενθουσιάζομαι με υπέρ-απλουστευμένα παραδείγματα γραμμένα από ανθρώπους που ξέρουν για τι πράγμα μιλάνε, δείχνοντας μερικά έξυπνα χαρακτηριστικά του Bash, τα οποία είναι τόσο έξω από το πλαίσιο τους ώστε να μην μπορείς να τα χρησιμοποιήσεις ποτέ σε πραγματικές συνθήκες. Μπορείτε να διαβάσετε τέτοια πράγματα αφού θα τελειώσετε αυτό τον οδηγό, ο οποίος περιέχει ασκήσεις και παραδείγματα, που θα σας βοηθήσουν να επιζήσετε στον πραγματικό κόσμο.

Από την εμπειρία μου ως χρήστης UNIX/Linux, διαχειριστής συστημάτων και εκπαιδευτής, ξέρω οτι πολλοί χρήστες μπορεί να χρησιμοποιούν χρόνια το σύστημά τους χωρίς να έχουν τη παραμικρή kγνώση για αυτοματοποίηση εργασιών. Έτσι συχνά θεωρούν οτι το UNIX δεν είναι φιλικό, ή ακόμη χειρότερα, οτι είναι αργό και ξεπερασμένο. Αυτό είναι ένα άλλο πρόβλημα που μπορείνα διορθωθεί με αυτό τον οδηγό.


2. Ποιός πρέπει να διαβάσει αυτό τον οδηγό;

Καθένας που δουλεύει σε συστήματα UNIX ή παρόμοια συστήματα και θέλει να κάνει τη ζωή του ευκολότερη, είτε είναι διαχειριστής ή ισχυρός χρήστης, μπορεί να κερδίσει από την ανάγνωση αυτού του εγχειριδιίου. Οι αναγνώστες που ήδη γνωρίζουν τη χρήση της γραμμής εντοών θα μάθουν να διευκολύνουν τις καθημερινές τους εργασίες με τη συγγραφή σεναρίων. Οι διχαχειριστές συστημάτων βασίζονται πολύ στα σενάρια φλοιού για την αυτοματοποίηση συχνά εκτελούμενων εργασιών. Το κείμενο αυτό είναι γεμάτο παραδείγματα που θα σας ενθαρρύνουν να γράψετε τα δικά σας σενάρια και θα σας εμπνεύσει να βελτιώσετε υπάρχοντα σενάρια.

Προαπαιτούμενα (ή μη) για την ανάγνωση: Πρέπει να:

         Είστε ένας έμπειρος χρήστης UNIX ή Linux, εξοικειωμένος με τις βασικές εντολές και τις σελίδες τεκμηρίωσης

         Μπορείτε να χρησιμοποιήσετε ένα συντάκτη κειμένου

         Κατανοείτε τη διαδικασία εκκίνσης και τερματισμού, το init και τα initscripts

         Μπορείτε να δημιουργείτε χρήστες, ομάδες και να ρυθμίζετε κωδικούς πρόσβασης

         Γνωρίζετε τα ζητήματα διαχείρισης αδειών πρόσβασης αρχείων

         Κατανοείτε τις συμβάσεις ονομασίας συσκευών, διαμέρισης, από/προσάρτησης συστημάτων αρχείων

         Μπορείτε να προσθαφαιρείτε λογισμικό στο σύστημά σας

Σε περίπτωση που δεν γνωρίζετε κάποιο από τα παραπάνω θέματα δείτε την Εισαγωγή στο Linux (ή το τοπικό TLDP mirror). Πρόσθετες πληροφορίες μπορούν να βρεθούν στη τεκμηρίωση του συστήματος (σελίδες man και info), ή στο Linux Documentation Project.


3. Νέες εκδόσεις, μεταφράσεις και διαθεσιμότητα

Η πιο πρόσφατη έκδοση μπορεί να βρεθέι στο http://tille.xalasys.com/training/bash/. Η ίδια έκδοση μπορεί να βρεθεί στο http://tldp.org/LDP/Bash-Beginners-Guide/html/index.html.

Ο οδηγός είναι διαθέσιμος σε έντυπη μορφή από το Fultus.com.

Εικόνα 1. Εξώφυλλο Bash Guide for Beginners

Εικόνα 1

Ο οδηγός έχει μεταφραστεί:

         Στα Κινεζικά στο http://xiaowang.net/bgb-cn/, από Wang Wei.

         Στα Ουκρανικά στο http://docs.linux.org.ua/index.php/LDP:Bash_beginners_guide, από τον Yaroslav Fedevych και την ομάδα του.

Προετοιμάζεται μια Γαλλική μετάφραση και θα αναρτηθεί σύντομα.

Η Ελληνική μετάφραση οφείλεται στον Κώστα Γ. Μαργαρίτη, στα πλαίσια της διδασκαλίας του μαθήματος Προγραμματισμός και Διαχείριση Συστημάτων ΙΙ, στο Τμήμα Εφαρμοσμένης Πληροφορικής του Πανεπιστημίου Μακεδονίας. Ειδικά ευχαριστώ τους φοιτητές του ακαδ. έτους 2006-7 για τις αρχικές προσπάθειες μετάφρασης.


4. Ιστορία αναθεωρήσεων

Revision History

Revision 1.8

2006-03-15

Revised by: MG

clarified example in Chap4, corrected here doc in chap9, general checks and correction of typos, added link to Chinese and Ukrainian translation, note and stuff to know about awk in chap6.

Revision 1.7

2005-09-05

Revised by: MG

Corrected typos in chapter 3, 6 and 7, incorporated user remarks, added a note in chap7.

Revision 1.6

2005-03-01

Revised by: MG

Minor debugging, added more keywords, info about new Bash 3.0, took out blank image.

Revision 1.5

2004-12-06

Revised by: MG

Changes because of new domain, minor corrections.

Revision 1.4

2004-10-18

Revised by: MG

Debugging, added a couple of notes in chap9, replaced screenshots with screen sections. Corrected some typos.

Revision 1.3

2004-07-09

Revised by: MG

Added tracer image 1x1 pixel http://tille.xalasys.com/images/blank-bash.png, added textobjects for all pictures, fixed wrong links in index, made signal list more clear.

Revision 1.2

2004-06-15

Revised by: MG

Added index, more markup in screen sections.

Revision 1.1

2004-05-22

Revised by: MG

Last read-through before going to press, added more examples, checked summaries, exercises, cleaned up introduction.

Revision 1.0

2004-04-27

Revised by: TM

Initial release for LDP; more exercises, more markup, less errors and abuse; added glossary.

Revision 1.0-beta

2003-04-20

Revised by: MG

Pre-release


5. Συνεισφορές

Ευχαριστω όλους τους φίλους που βοήθησαν (ή προσπάθησαν) και τον σύζυγό μου, του οποίου οι ενθαρρυντικά λόγια έκαναν τη δουλειά αυτή δυνατή. Ευχαριστώ όλους που έστειλαν αναφορές σφαλμάτων και άλλα σχόλια. Μεταξύ άλλων:

         Hans Bol, ένας από τους οπαδούς

         Mike Sim, σχόλια για το στυλ

         Dan Richter, παραδείγματα πινάκων

         Gerg Ferguson, ιδέες για τον τίτλο

         Mendel Leo Cooper, για τον χώρο

         #linux.be, γιατί με κρατά προσγειωμένη

         Frank Wang, για τα λεπτομερή σχόλια για όλα που έκανα στραβά ;-)

Ειδικά ευχαριστώ τη Tabatha Marshall, που εθελοντικά έκανε μια πλήρη ανάγνωση και διόρθωση ορθογραφικών και γραμματικών σφαλμάτων. Κάνουμε πολύ καλή ομάδα: αυτή δουλεύει ενώ εγώ κοιμάμαι. Και αντιστρόφως ;-)


6. Ανάδραση

Σχόλια, πληροφορίες, σφάλαματ, ελλείψεις; Mail στο

<tille wants no spam _at_ xalasys dot com>


7. Πληροφορίες Copyright

Copyright 2003-2005 Machtelt Garrels.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being "New versions of this document", "Contributions", "Feedback" and "Copyright information", with no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in Appendix B entitled "GNU Free Documentation License".

The author and publisher have made every effort in the preparation of this book to ensure the accuracy of the information. However, the information contained in this book is offered without warranty, either express or implied. Neither the author nor the publisher nor any dealer or distributor will be held liable for any damages caused or alleged to be caused either directly or indirectly by this book.

The logos, trademarks and symbols used in this book are the properties of their respective owners.


8. Τι χρειάζεστε;

Ο φλοιός bash διαθέσιμος στο http://www.gnu.org/directory/GNU/. Ο φλοιός bash βρίσκεται σχεδόν σε κάθε σύστημα Linux, και σε αρκετά συστήματα UNIX.

Μεταγλωττίζεται εύκολα, αν δεν το βρείτε προεγκατεστημένο, και έχει ελεγχθεί σε πολλά συστήματα UNIX, Linux, MS Windows και άλλα.


9. Συμβάσεις του κειμένου

Στο κείμενο ακολουθούνται οι παρακάτων τυπογραφικές συμβάσεις:

Πίνακας 1. Τυπογραφικές συμβάσεις

Τύπος κειμένου

Σημασία

"Κείμενο σε εισαγωγικά"

Αυτούσια μεταφορά κειμένου από πρόσωπα ή έξοδο υπολογιστή

έξοδος τερματικού

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

εντολή

Όνομα εντολής όπως εισάγεται στη γραμμή εντολών

ΜΕΤΑΒΛΗΤΗ

Όνομα μεταβλητής ή δείκτης στο περιεχόμενο (τιμή) μεταβλητής, όπως στo $ΜΕΤΑΒΛΗΤΗ.

επιλογή

Επιλογή σε μια εντολή, όπως η "επιλογή -a στην εντολή ls".

όρισμα

Όρισμα εντολής, όπως "διαβάστε το man ls".

εντολή επιλογές ορίσματα

Σύνοψη γενικής χρήσης εντολής, σε ξεχωριστή γραμμή.

όνομα_αρχείου

Όνομα αρχείου ή καταλόγου, για παράδειγμα "Αλλαγή στον κατάλογο /usr/bin "

Πλήκτρο

Πλήκτρο του πληκτρολογίου, όπως "πιέστε Q για έξοδο".

Κουμπί

Γραφικό κουμπί για επιλογή (click), όπως το κουμπί OK.

Μενού->Επιλογή

Επιλογή από γραφικό μενού, λόγου χάρη: "Επιλέξτε Help->About Mozilla στο περιηγητή σας."

Ορολογία

Σημαντικός όρος ή έννοια: "Ο πυρήνας του Linux είναι η καρδιά του συστήματος."

\

Το backslash σε έξοδο τερματικού ή σε σύνοψη εντολής δηλώνει συνέχεια. Με άλλα λόγια, αν δείτε μια μεγάλη εντολή τεμαχισμένη σε πολλές γραμμές, το \ σημαίνει "Μη πιέσετε ακόμη Enter !"

Δείτε Κεφάλαιο 1

Σύνδεσμος σε σχετικό θέμα μέσα στο κείμενο.

Ο συγγραφέας

Σύνδεσμος σε εξωτερικό πόρο ιστού.


10. Οργάνωση του κειμένου

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

Τα κεφάλαια τέσσερα έως έξι συζητούν τα βασικά εργαλεία που συνήθως χρησιμοποιούνται στα σενάρια φλοιού.

Τα κεφάλαια οκτώ έως δώδεκα συζητούν τις συνηθέστερες δομές των σεναρίων φλοιού.

Όλα τα κεφάλαια συνοδεύονται από ασκήσεις που εξετάζουν την ετοιμότητά σας για το επόμενο κεφάλαιο.

         Κεφάλαιο 1: Τα βασικά του Bash: γιατί το Bash είναι τόσο καλό, δομικά τμήματα, πρώτες οδηγίες για την ανάπτυξη καλών σεναρίων.

         Κεφάλαιο 2: Τα βασικά των σεναρίων: συγγραφή και εκσφαλμάτωση.

         Κεφάλαιο 3: Το περιβάλλον του Bash: αρχεία ρύθμισης, μεταβλητές, αυτούσια εμφάνιση χαρακτήρων, σειρά επέκτασης φλοιού, ψευδώνυμα, επιλογές.

         Κεφάλαιο 4: Κανονικές εκφράσεις: μια εισαγωγή.

         Κεφάλαιο 5: Sed:εισαγωγή στον διορθωτή γραμμής sed.

         Κεφάλαιο 6:Awk: εισγωγή στη γλώσσα προγραμματισμού awk.

         Κεφάλαιο 7: Δηλώσεις υπο συνθήκη: δομές του Bash για έλεγχο συνθηκών.

         Κεφάλαιο 8: Διαλογικά σενάρια: κάνοντας τα σενάρια φιλικά στο χρήστη, ανάγνωση εισόδου από το χρήστη.

         Κεφάλαιο 9: Επαναληπτική εκτέλεση εντολών: δομές του Bash για αυτόματη εκτέλεση εντολών.

         Κεφάλαιο 10: Προχωρημένες μεταβλητές: ορισμός τύοων μεταβλητών, εισαγωγή στους πίνακες μεταβλητών, πράξεις με μεταβλητές.

         Κεφάλαιο 11: Συναρτήσεις: μια ειαγωγή.

         Κεφάλαιο 12: Σύλληψη σημάτων: εισγωγή στη σηματοδοσία διεργασιών και στη παγίδευση σημάτων χρηστών.


Κεφάλαιο 1. Bash και σενάρια Bash

Σε αυτό το εισαγωγικό κεφάλαιο

         Περιγράφουμε ορισμένους σηνήθεις φλοιούς

         Τονίζουμε κάποια πλεονεκτήματα και χαρακτηριστικά του GNU Bash

  • Περιγράφουμε τα δομικά μέρη του φλοιού

         Συζητούμε για αρχεία εκκίνησης του Bash

  • Βλέπουμε πως ο φλοιός εκτελεί εντολές

         Αναφερόμαστε σε μερικά απλά παραδείγματα σεναρίων


1.1. Κοινά προγράμματα φλοιού

1.1.1. Γενικές λειτουργίες φλοιού

Το πρόγραμμα φλοιού των UNIX διερμηνεύει εντολές του χρήστη, που είτε πληκτρολογούνται άμεσα από τον χρήστη, είτε μπορούν να διαβαστούν από ένα αρχείο που ονομάζεται σενάριο φλοιού ή πρόγραμμα φλοιού. Τα σενάριαφλοιού είναι διερμηνευόμεα, όχι μεταγλωττιζόμενα. Ο φλοιός διαβάζει τις εντολές από το σενάριο μια προς μια και τις αναζητά στο σύστημα (βλέπε Ενότητα 1.2), ενώ ο μεταγλωττιστής μετατρέπει ένα πρόγραμμα σε γλώσσα μηχανής, ένα εκτελέσιμο αρχείο που τότε μπορεί να χρησιμοποιηθεί σαν εντολή σε ένα σενάριο φλοιού.

Εκτός από το να περνάει εντολές στον πυρήνα, η κύρια αποστολή του φλοιού είναι να παρέχει ένα περιβάλλον χρήστη, που μπορεί να τροποποιηθεί χρησιμοποιώντας αρχεία κειμένου για τη ρύθμιση  του φλοιού.


1.1.2. Είδη φλοιών

Όπως οι άνθρωποι κατανοούν διαφορετικές γλώσσες και διαλέκτους, το UNIX προσφέρει συνήθως μια ποικιλία φλοιών:

         sh ή Bourne φλοιός: ο γνήσιος φλοιός που χρησιμοποιείται ακόμα σε συστήματα UNIX και σε σχετικά με UNIX περιβάλλοντα. Είναι ο βασικός φλοιός, ένα μικρό πρόγραμμα με λίγα χαρακτηριστικά. Ενώ δεν είναι ο τυπικός φλοιός, είναι ακόμα διαθέσιμος σε κάθε σύστημα Linux για συμβατότητα με προγράμματα UNIX.

         bash ή Bourne Again φλοιός: ο τυπικός GNU φλοιός, διαισθητικός και ευέλικτος. Πιθανόν η καλύτερη επιλογή για αρχάριους χρήστες ενώ είναι παράλληλα ένα πολύ ισχυρό εργαλείο για τον προχωρημένο και τον επαγγελματία χρήστη. Στα Linux, ο bash είναι ο τυπικός φλοιός για απλούς χρήστες. Αυτός ο φλοιός είναι το λεγόμενο υπέρ-πακέτο του φλοιού Bourne, ένα πακέτο με add-ons και plug-ins. Αυτό σημαίνει ότι ο Bourne Again φλοιός είναι συμβατός με τον φλοιό Bourne: εντολές που τρέχουν στον sh, τρέχουν επίσης στον bash. Ωστόσο, κρατείστε πάντα μια μικρή επιφύλαξη. Όλα τα παραδείγματα και οι ασκήσεις σε αυτό το βιβλίο χρησιμοποιούν τον bash.

         csh ή C  φλοιός: η σύνταξη αυτού του φλοιού μοιάζει με αυτήν της γλώσσας προγραμματισμού C

         tcsh ή Turbo C φλοιός: ένα υπέρ-πακέτο του κοινού C φλοιού, με βελτιώσεις στην φιλικότητα προς τον χρήστη και την ταχύτητα.

         ksh ή Korn φλοιός: μερικές φορές εκτιμάται από ανθρώπους με υπόβαθρο UNIX. Ένα υπέρ-πακέτο του φλοιού Bourne, με την βασική προειδοποίηση οτι είναι ένας εφιάλτης για τους αρχάριους προγραμματιστές.

Το αρχείο /etc/shells δίνει μια σύνοψη των γνωστών φλοιών του συστήματος Linux:

 
mia:~> cat /etc/shells
/bin/bash
/bin/sh
/bin/tcsh
/bin/csh

Ο προεπιλεγμένος φλοιός βρίσκεται στο αρχείο /etc/passwd , όπως αυτή η γραμμή για την χρήστη Mia:

 

 
mia:L2NOfqdlPrHwE:504:504:Mia Maya:/home/mia:/bin/bash

Για να αλλάξετε από έναν φλοιό σε άλλον, απλώς εισάγετε το όνομα του νέου φλοιού στο ενεργό τερματικό. Το σύστημα βρίσκει τον κατάλογο στο οποίο παραπέμπει το όνομα χρησιμοποιώντας τις ρυθμίσεις PATH, και αφού ο φλοιός είναι ένα εκτελέσιμο αρχείο, ο τρέχων φλοιός τον ενεργοποιεί και εκτελείται. Συνήθως ένα διαφορετικό σύμβολο προτροπής εμφανίζεται, επειδή κάθε φλοιός έχει την δική του τυπική εμφάνιση:

 
mia:~> tcsh
[mia@post21 ~]$

1.2. Πλεονεκτήματα του φλοιού Bourne Again

1.2.1. Το Bash είναι ο GNU φλοιός

Το έργο GNU (GNU δεν είναι UNIX) παρέχει εργαλεία για διαχείριση συστημάτων τύπου UNIX τα οποία είναι ελεύθερο λογισμικό και σύμφωνα με τα πρότυπα του UNIX.

Το Bash είναι ένας sh-συμβατός φλοιός που ενσωματώνει χρήσιμα χαρακτηριστικά του φλοιού Korn (ksh) και του φλοιού C (csh). Είναι σύμφωνος με τον φλοιό ΙΕΕΕ POSIX Ρ1003.2/ISO 9945.2 και με τα πρότυπα εργαλεία (Tools). Προσφέρει λειτουργικές βελτιώσεις όχι μόνο για προγραμματιστική αλλά και για αλληλεπιδραστική χρήση. Αυτά περιλαμβάνουν επεξεργασία γραμμής εντολών, απεριόριστο μέγεθος ιστορικού εντολών, έλεγχο εργασιών, λειτουργίες φλοιού και ψευδώνυμα, πίνακες με δείκτες απείρου μεγέθους και αριθμητική ακεραίων σε κάθε βάση από το 2 μέχρι το 64. O Bash μπορεί να εκτελέσειι τα περισσότερα από τα σενάρια sh χωρίς τροποποίηση.

 

Όπως τα άλλα έργα GNU, το έργο bash διατηρεί, προστατεύει και προωθεί την ελευθερία στην χρήση, μελέτη, αντιγραφή, τροποποίηση και αναδιανομή λογισμικού. Είναι γενικά γνωστό ότι τέτοιες συνθήκες υποκινούν την δημιουργικότητα. Αυτό είναι επίσης αλήθεια και με το λογισμικό bash, το οποίο έχει πολλά επιπλέον χαρακτηριστικά τα οποία άλλοι φλοιοί δεν μπορούν να προσφέρουν.

 


1.2.2. Αποκλειστικά χαρακτηριστικά του φλοιού Bash

1.2.2.1. Κλήση

Αντίθετα με τις επιλογές γραμμής εντολών ενός μόνο χαρακτήρα, που μπορούν γενικά να τροποποιηθούν χρησιμοποιώντας την ενσωματωμένη εντολή φλοιού set, υπάρχουν αρκετές επιλογές πολλών χαρακτήρων που μπορείούμε να χρησιμοποιήσουμε. Θα βρεθούμε απέναντι σε κάποιες από τις πιο γνωστές επιλογές σε αυτό και στα επόμενα κεφάλαια. Η ολοκληρωμένη λίστα υπάρχει στις σελίδες πληροφοριών του φλοιού Bash, χαρακτηριστικά του Bash->Κλήση Bash.


1.2.2.2. Αρχεία εκκίνησης του Bash

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

 


1.2.2.2.1. Κλήση διαλογικού φλοιού σύνδεσης, ή κλήση με '--login'

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

Ανάγνωση αρχείων:

         /etc/profile

         ~/.bash_profile, ~/.bash_login ή ~/.profile: διαβάζεται το πρώτο αναγνώσιμο αρχείο που υπάρχει

         ~/.bash_logout στην αποσύνδεση.

Μηνύματα σφάλματος εκτυπώνονται αν τα αρχεία διαμόρφωσης υπάρχουν αλλά δεν είναι αναγνώσιμα. Αν ένα αρχείο δεν υπάρχει, το bash ψάχνει για το επόμενο.

 


1.2.2.2.2. Κλήση διαλογικού φλοιού μη-σύνδεσης

Ένας φλοιός μη-σύνδεσης σημαίνει ότι δεν απαιτείται ταυτοποίηση από το σύστημα. Για παράδειγμα, όταν ανοίγουμε ένα τερματικό χρησιμοποιώντας ένα εικονίδιο, ή ένα αντικείμενο menu, αυτός είναι ο φλοιός μη-σύνδεσης.

Ανάγνωση αρχείων:

         ~/.bashrc

Αυτό το αρχείο συνήθως αναφέρεται στο ~/.bash_profile:

if [ -f ~/.bashrc ]; then . ~/.bashrc; fi

Βλέπε Κεφάλαιο 7 για περισσότερες πληροφορίες σχετικά με την δομή if.


1.2.2.2.3. Μη-διαλογική κλήση

Όλα τα σενάρια χρησιμοποιούν μη-διαλογικούς φλοιούς. Είναι προγραμματισμένα να εκτελέσουν ορισμένες εργασίες και δεν μπορούν να καθοδηγηθούν στο να κάνουν άλλες δουλειές παρά μόνο αυτές για τις οποίες έχουν προγραμματιστεί.

Ανάγνωση αρχείων:

         καθορίζεται από τη μεταβλητή BASH_ENV

Η PATH δεν χρησιμοποιείται για την αναζήτηση αυτού του αρχείου, έτσι αν θέλετε να το χρησιμοποιήσετε, καλύτερα αναφερθείτε σε αυτό δίνοντας ολόκληρη την διαδρομή και το όνομα του αρχείου.

 


1.2.2.2.4. Κλήση με την εντολή sh

Το Bash προσπαθεί να συμπεριφέρεται σαν το ιστορικό Bourne sh πρόγραμμα ενώ παράλληλα προσαρμόζεται στο POSIX πρότυπο.

Ανάγνωση αρχείων:

         /etc/profile

         ~/.profile

Όταν η κλήση είναι διαλογική , η μεταβλητή ΕΝV μπορεί να δείξει επιπλέον πληροφορίες εκκίνησης.


1.2.2.2.5. Κατάσταση POSIX

Αυτή η επιλογή ενεργοποιείται είτε χρησιμοποιώντας την ενσωματωμένη εντολή set:

set -o posix

είτε καλώντας το πρόγραμμα bash με την --posix επιλογή. Το Bash τότε θα προσπαθήσει να συμπεριφερθεί όσο το δυνατό σύμφωνα με το POSIX πρότυπο για φλοιούς. Θέτοντας την POSIXLY_CORRECT μεταβλητή πετυχαίνουμε το ίδιο.

Ανάγνωση αρχείων:

         καθορίζεται από τη μεταβλητή ENV.


1.2.2.2.6. Απομακρυσμένη κλήση

Ανάγνωση αρχείων όταν ο φλοιός καλείται με rshd:

         ~/.bashrc

Warning

Αποφυγή χρήσης των r-εργαλείων

 

Προσοχή στους κινδύνους της χρήσης εργαλείων όπως rlogin, telnet, rsh και rcp. Είναι εντελώς ανασφαλή επειδή εμπιστευτικά δεδομένα στέλνονται μέσω του δικτύου χωρίς να κρυπτογραφηθούν. Αν χρειάζεστε εργαλεία για απομακρυσμένη εκτέλεση, μεταφορά αρχείων κ.α., χρησιμοποίησε μια εφαρμογή του Secure SHell, γενικώς γνωστός ως SSH, ο οποίος διατίθεται ελεύθερα από την http://www.openssh.org. Διαφορετικά προγράμματα πελάτη είναι διαθέσιμα για μη-UNIX συστήματα επίσης, δείτε στο τοπικό σας αποθετήριο λογισμικού.


1.2.2.2.7. Κλήση όταν το UID δεν είναι ίσο με το EUID

Στην περίπτωση αυτή δεν διαβάζονται αρχεία εκκίνησης.


1.2.2.3. Διαλογικοί φλοιοί 

1.2.2.3.1. Τι είναι ένας διαλογικός φλοιός;

Ένας διαλογικός φλοιός συνήθως διαβάζει από, και γράφει σε, ένα τερματικό χρήστη: η πρότυπη είσοδος και έξοδος είναι συνδεδεμένες σε ένα τερματικό. Η διαλογική συμπεριφορά του Bash ξεκινάει όταν η εντολή bash καλείται χωρίς άλλα ορίσματα παρά μόνο με επιλογές, εκτός από την περίπτωση που η επιλογή είναι μια συμβολοσειρά από όπου πρέπει να διαβάσει ο φλοιός ή όταν ο φλοιός έχει κληθεί να διαβάσει από πρότυπη είσοδο, η οποία επιτρέπει σε παραμέτρους θέσης να οριστούν (βλέπε Κεφάλαιο 3 ).


1.2.2.3.2. Είναι αυτός ο φλοιός διαλογικός;

Δοκίμασε το κοιτάζοντας το περιεχόμενο της ειδικής παραμέτρου -, η οποία περιέχει ένα 'i' όταν ο φλοιός είναι διαλογικός:

 
eddy:~> echo $-
himBH

Σε μη-διαλογικούς φλοιούς, η προτροπή PS1 δεν είναι ορισμένη.


1.2.2.3.3. Συμπεριφορά διαλογικού φλοιού

Διαφορές στην διαλογική κατάσταση:

         Ο Bash διαβάζει αρχεία εκκίνησης.

         Ο έλεγχος εργασιών είναι προεπιλογμένος.

         Ορίζονται οι προτροπές, η PS2 ενεργοποιείται για εντολές πολλών γραμμών, και είναι συνήθως ορισμένη σε ">". Αυτή είναι επίσης η προτροπή που λαμβάνουμε όταν ο φλοιός θεωρεί ότι εισάγουμε μια ανολοκλήρωτη εντολή, για παράδειγμα όταν ξεχνάμε εισαγωγικά, δομές εντολών που δεν μπορούν να παραλειφθούν κτλ.

         Οι εντολές διαβάζονται από την γραμμή εντολών με την readline (προεπιλογή).

         Το Bash διερμηνεύει την επιλογή φλοιού ignoreeof αντί να τερματίζεται αμέσως μόλις λάβει  EOF (End Of File).

         Το ιστορικό εντολών και οι επεκτάσεις ιστορικού είναι ενεργοποιημένες ως προεπιλογή. Το ιστορικό αποθηκεύεται στο αρχείο που υποδεικνύει η HISTFILE όταν κλείνει ο φλοιός. Ως προεπιλογή, η HISTFILE υποδεικνύει το ~/.bash_history.

         Η επέκταση ψευδωνύμων είναι ενεργοποιημένη.

         Αν δεν υπάρχουν παγίδες (traps), το SIGTERM σήμα αγνοείται.

         Αν δεν υπάρχουν παγίδες (traps), το SIGINT ανιχνεύεται και υφίσταται διαχείριση. Έτσι, πατώντας Ctrl+C, για παράδειγμα, ο διαλογικός φλοιός δεν τερματίζεται.

         Η αποστολή SIGHUP σημάτων σε όλες τις εργασίες κατά την αποσύνδεση ρυθμίζεται με την επιλογή huponexit.

         Οι εντολές εκτελούνται μόλις διαβαστούν.

         Το Bash ελέγχει περιοδικά για αλληλογραφία.

         Το Bashμπορεί να ρυθμιστεί ώστε να τερματίζεται όταν αντιμετωπίζει μεταβλητές που δεν έχουν οριστεί. Στην διαλογική αυτή η συμπεριφορά είναι απενεργοποιημένη.

         Όταν οι εσωτερικές εντολές του φλοιού αντιμετωπίζουν σφάλματα ανακατεύθυνσης, ο φλοιός δεν αναγκάζεται να τερματιστεί.

         Σφάλματα που επιστρέφονται από εντολές που χρησιμοποιούνται σε κατάσταση POSIX δεν αναγκάζουν τον φλοιό να τερματιστεί. Οι εσωτερικές εντολές παρουσιάζονται στην Ενότητα 1.3.

         Αποτυχία του exec δεν θα τερματίσει τον φλοιό.

         Λανθασμένη συντακτική ανάλυση δεν αναγκάζει τον φλοιό να τερματιστεί.

         Προεπιλεγμένος απλός ορθογραφικός έλεγχος για τα ορίσματα στην εσωτερική εντολή cd.

         Ενεργοποίηση αυτόματης εξόδου μετά την πάροδο του χρόνου που ορίστηκε στην μεταβλητή TMOUT.

Περισσότερες πληροφορίες:

         Ενότητα 3.2

         Ενότητα 3.6

         Δείτε Κεφάλαιο 12 για περισσότερα σχετικά με τα σήματα.

         Η Ενότητα 3.4αναφέρεται στις διάφορες επεκτάσεις που εκτελούνται κατά την εισαγωγή μιας εντολής.


1.2.2.4. Συνθήκες

Οι  εκφράσεις υπό συνθήκη χρησιμοποιούνται από την σύνθετη εντολή [[ και από τις εσωτερικές εντολές test και [.

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

Υπάρχουν αλφαριθμητικοί τελεστές αλλά και συγκριτικοί αριθμητικοί τελεστές επίσης: αυτοί είναι δυαδικοί τελεστές, χρειάζονται δυο αντικείμενα για την διαδικασία. Αν το όρισμα FILE σε ένα από τα μέλη της συνθήκης είναι της μορφής /dev/fd/N, τότε ελέγχεται ο περιγραφέας αρχείου N. Αν το όρισμα FILE σε ένα από τα μέλη της συνθήκης είναι της μορφής /dev/stdin, /dev/stdout ή /dev/stderr, τότε ελέγχεται ο περιγραφέας αρχείου 0, 1 ή 2.

Οι συνθήκες παρουσιάζονται λεπτομερειακά στο Κεφάλαιο 7.

Περισσότερες πληροφορίες σχετικά με τους περιγραφείς αρχείου στην Ενότητα 8.2.3.


1.2.2.5. Αριθμητική φλοιού

Ο φλοιός επιτρέπει την αποτίμηση αριθμητικών εκφράσεων, είτε μέσω μιας από της επεκτάσεις φλοιού ή μέσω της εσωτερικής εντολής let.

Η αποτίμηση εκτελείται σε ακεραίους σταθερού εύρους χωρίς έλεγχο για υπερχείλιση, ωστόσο η διαίρεση με το 0 ανιχνεύεται και σημειώνεται ως σφάλμα. Οι τελεστές και η προτεραιότητα και η προτεραιότητά τους  είναι ίδια με την γλώσσα C, βλέπε Κεφάλαιο 3.


1.2.2.6. Ψευδώνυμα

Τα ψευδώνυμα επιτρέπουν σε ένα αλφαριθμητικό να υποκαθίσταται από ένα άλλο όταν χρησιμοποιείται ως η πρώτη λέξη μιας απλής εντολής. Ο φλοιός διατηρεί την λίστα των ψευδωνύμων που μπορεί να ενεργοποιηθεί ή να απενεργοποιηθεί με τις alias και unalias εντολές.

Το Bash πάντα διαβάζει τουλάχιστον μια ολόκληρη γραμμή εισόδου πριν εκτελέσει οποιαδήποτε από τις εντολές σε αυτή τη γραμμή. Τα ψευδώνυμα επεκτείνονται όταν διαβάζεται μια εντολή, όχι όταν εκτελείται. Επομένως, ένας ορισμός ψευδωνύμου που εμφανίζεται στην ίδια γραμμή με μια άλλη εντολή δεν εφαρμόζεται μέχρι να διαβαστεί η επόμενη γραμμή εισόδου. Οι εντολές που ακολουθούν τον καθορισμό των ψευδωνύμων σε αυτή την γραμμή δεν επηρεάζονται από τα καινούρια ψευδώνυμα.

Τα ψευδώνυμα επεκτείνονται όταν διαβάζεται ένας ορισμός συνάρτησης, όχι όταν μια συνάρτηση εκτελείται, επειδή ο ορισμός συνάρτησης είναι από μόνος του μια σύνθετη εντολή. Ως συνέπεια, τα ψευδώνυμα που ορίζονται σε μια συνάρτηση δεν είναι διαθέσιμα πριν την εκτέλεση της συνάρτησης.

Θα εξετάσουμε λεπτομερώς τα ψευδώνυμα στην Ενότητα 3.5.


1.2.2.7. Πίνακες

Το Bash παρέχει μεταβλητές μονοδιάστατου πίνακα. Κάθε μεταβλητή μπορεί να χρησιμοποιηθεί σαν πίνακας: η εσωτερική εντολή declare δηλώνει ρητά έναν πίνακα. Δεν υπάρχει ανώτατο όριο στο μέγεθος ενός πίνακα, ούτε καμία απαίτηση τα μέλη να εισάγονται ή να ορίζονται συνεχόμενα. Οι πίνακες έχουν ως βάση το 0. Βλέπε Κεφάλαιο 10.


1.2.2.8. Στοίβα καταλόγων

Η στοίβα καταλόγων είναι μια λίστα των πρόσφατα προσπελασμένων καταλόγων. Η εσωτερική εντολή pushd προσθέτει καταλόγους στη στοίβα καθώς αλλάζει ο τρέχων κατάλογος, και η εσωτερική εντολή popd αφαιρεί καταλόγους από την στοίβα και αλλάζει τον τρέχοντα κατάλογο με τον κατάλογο που αφαίρεσε.

Το περιεχόμενο μπορεί να προβληθεί χρησιμοποιώντας την εντολή dirs ή ελέγχοντας το περιεχόμενο της μεταβλητής DIRSTACK.

Περισσότερες πληροφορίες σχετικά με την λειτουργία αυτού του μηχανισμού βρίσκονται στις σελίδες πληροφοριών για το Bash.


1.2.2.9. Η προτροπή

Το Bash κάνει το παιχνίδι με την προτροπή ακόμα πιο διασκεδαστικό. Βλέπε την ενότητα Ελέγχοντας την προτροπή στις σελίδες πληροφοριών για τον Bash.


1.2.2.10. Ο περιορισμένος φλοιός

Όταν καλείται ως rbash ή με την επιλογή --restricted ή -r, συμβαίνουν τα ακόλουθα:

         Η εσωτερική εντολή cd είναι απενεργοποιημένη.

         Η ρύθμιση των μεταβλητών SHELL, PATH, ENV or BASH_ENV δεν είναι δυνατή.

         Τα ονόματα των εντολών δεν μπορούν πλέον να περιέχουν slash (/).

         Ονόματα αρχείων που περιέχουν '/' δεν γίνονται δεκτά με την εσωτερική εντολή . (source).

         Η εσωτερική εντολή hash δεν αποδέχεται το '/'με την επιλογή -p.

         Η εισαγωγή συναρτήσεων στην εκκίνηση δεν επιτρέπεται.

         Κατά την εκκίνηση αγνοείτα η μεταβλητή SHELLOPTS.

         Η επανακατεύθυνση της εξόδου χρησιμοποιώντας  >, >|, ><, >&, &> and >> είναι απενεργοποιημένη.

         Η εσωτερική εντολή exec είναι απενεργοποιημένη.

         Οι -f και -dεπιλογές είναι απενεργοποιημένες για την εσωτερική εντολή enable.

         Η εσωτερική εντολή command δεν μπορεί να προσδιορίσει ένα προεπιλεγμένο PATH.

         Δεν είναι δυνατή η απενεργοποίηση της περιορισμένης λειτουργίας.

Όταν εκτελείται μια εντολή που τυχαίνει να είναι ένα σενάριο φλοιού, η rbash απενεργοποιεί οποιουσδήποτε περιορισμούς στον φλοιό ώστε να εκτελέσει το σενάριο.

Περισσότερες πληροφορίες:

         Ενότητα 3.2

         Ενότητα 3.6

         Πληροφορίες Bash->Βασικά χαρακτηριστικά του Bash->Ανακατευθύνσεις

         Ενότητα 8.2.3: προχωρημένες ανακατευθύνσεις.


1.3. Εκτέλεση εντολών

1.3.1. Γενικά

Το Bashκαθορίζει τον τύπο προγράμματος που πρόκειται να εκτελεστεί. Τα κανονικά προγράμματα είναι εντολές συστήματος που υπάρχουν σε μεταγλωττισμένη μορφή στο σύστημα. Όταν ένα τέτοιο πρόγραμμα εκτελείται, δημιουργείται μια νέα διεργασία καθώς το Bash κάνει ένα ακριβές αντίγραφο του εαυτού του. Αυτή η θυγατρική διεργασία έχει το ίδιο περιβάλλον με την γονική διεργασία της, μόνο που ο αριθμός PID της διεργασίας είναι διαφορετικός. Αυτή η διαδικασία ονομάζεται forking (διακλάδωση).

Μετά τη διακλάδωση, ο χώρος διευθύνσεων της θυγατρικής διεργασίας εγγράφεται με τα νέα δεδομένα της διεργασίας. Αυτό γίνεται μέσω της κλήσης της exec από το σύστημα.

Έτσι ο μηχανισμός  fork-and-exec αλλάζει μια παλιά εντολή με μια καινούρια, όταν το περιβάλλον στο οποίο το καινούριο πρόγραμμα εκτελείται παραμένει το ίδιο, περιλαμβανομένων των ρυθμίσεων των συσκευών εισόδου και εξόδου,  των μεταβλητών περιβάλλοντος και της προτεραιότητας. Αυτός ο μηχανισμός συνηθίζεται να δημιουργεί όλες τις διεργασίες UNIX, πράγμα που ισχύει επίσης και στο Linux. Ακόμη και η πρώτη επεξεργασία, init, με αριθμό PID 1, διακλαδίζεται κατά τη διάρκεια της διαδικασίας εκκίνησης στo λεγόμενo bootstrapping.


1.3.2. Εσωτερικές εντολές φλοιού

Οι εσωτερικές (ενσωματωμένες) εντολές περιέχονται μέσα στον φλοιό. Όταν το όνομα μιας εσωτερικής εντολής χρησιμοποιείται σαν την πρώτη λέξη μιας απλής εντολής, ο φλοιός εκτελεί την εντολή άμεσα, χωρίς να δημιουργήσει μια καινούρια διεργασία. Οι εσωτερικές εντολές είναι απαραίτητες για την υλοποίηση λειτουργιών που θα ήταν ασύμφορο ή αδύνατο να υλοποιηθούν με εξωτερικές εντολές.

Το Bash υποστηρίζει 3 τύπους εσωετρικών εντολών:

         Εσωτερικές εντολές φλοιού Bourne:

:, ., break, cd, continue, eval, exec, exit, export, getopts, hash, pwd, readonly, return, set, shift, test, [, times, trap, umask και unset.

         Εσωτερικές εντολές φλοιού Bash:

alias, bind, builtin, command, declare, echo, enable, help, let, local, logout, printf, read, shopt, type, typeset, ulimit και unalias.

         Ειδικές εσωτερικές εντολές:

Όταν το Bash εκτελείται σε κατάσταση POSIX , οι ειδικές εσωτερικές εντολές διαφέρουν από άλλες εσωτερικές εντολές σε τρία σημεία:

1.      Οι ειδικές εσωτερικές εντολές προηγούνται των συναρτήσεων φλοιού κατά την αναζήτηση εντολών.

2.      Αν μια ειδική εσωτερική εντολή επιστρέφει μήνυμα λάθους, ένας μη-διαλογικός φλοιός τερματίζεται.

3.      Εντολές εκχώρησης που προηγούνται της εντολής μένουν σε λειτουργία στο περιβάλλον του φλοιού μετά την ολοκλήρωση της εντολής.

Οι ειδικές εσωτερικές εντολές του POSIX είναι :, ., break, continue, eval, exec, exit, export, readonly, return, set, shift, trap και unset.

Οι περισσότερες από αυτές τις εσωτερικές εντολές θα συζητηθούν σε επόμενα κεφάλαια. Για τις εντολές που δεν συζητούνται, αναφερθείτε στις σελίδες πληροφοριών.


1.3.3. Εκτέλεση προγράμματος από ένα σενάριο

Όταν το πρόγραμμα που εκτελείται είναι ένα σενάριο φλοιού, το Bash δημιουργεί μια καινούρια διεργασία bash χρησιμοποιώντας μια διακλάδωση (fork). Αυτός ο υποφλοιός διαβάζει τις γραμμές από το σενάριο φλοιού, μια κάθε φορά. Οι εντολές σε κάθε γραμμή διαβάζονται, διερμηνεύονται και εκτελούνται σαν να είχαν έρθει κατευθείαν από το πληκτρολόγιο.

Όταν ο υποφλοιός επεξεργάζεται κάθε γραμμή του σεναρίου, ο γονικός φλοιός περιμένει την επεξεργασία του θυγατρικού φλοιού να τελειώσει. Όταν πλέον δεν υπάρχουν άλλες γραμμές προς ανάγνωση στο σενάριο, ο υποφλοιός τερματίζεται. Ο γονικός φλοιός ενεργοποιείται και εμφανίζει μια καινούρια προτροπή.


1.4. Δομικά μέρη

1.4.1. Δομικά μέρη φλοιού

1.4.1.1. Σύνταξη φλοιού

Αν η είσοδος δεν είναι σχολιασμένη, ο φλοιός την διαβάζει και την διαιρεί σε τελεστές και λέξεις, υιοθετώντας κανόνες αναφοράς (quoting) για να προσδιορίσει το νόημα κάθε χαρακτήρα εισόδου. Κατόπιν  οι λέξεις και οι τελεστές μεταφράζονται σε εντολές και άλλες δομές, που επιστρέφουν μια κατάσταση εξόδου (exit status) διαθέσιμη για διερεύνηση ή επεξεργασία. Το παραπάνω fork-and-exec σχέδιο εφαρμόζεται μόνο αφού ο φλοιός έχει αναλύσει την είσοδο με τον ακόλουθο τρόπο:

         Ο φλοιός διαβάζει την είσοδό του από ένα αρχείο, από ένα αλφαριθμητικό ή από ένα τερματικό χρήστη.

         Η είσοδος διαχωρίζεται σε λέξεις και τελεστές, υπακούοντας τους κανόνες αναφοράς, βλέπε Κεφάλαιο 3. Αυτά τα σύμβολα (tokens) διαχωρίζονται με μεταχαρακτήρες. Η επέκταση των ψευδωνύμων εκτελείται.

         Ο φλοιός σαρώνει  (αναλύει και αντικαθιστά) τα σύμβολα με απλές και σύνθετες εντολές.

         Το Bash εκτελεί διάφορες επεκτάσεις φλοιού, αναλύοντας τα επεκταμένα σύμβολα σε λίστες με ονόματα αρχείων, εντολές και ορίσματα.

         Η ανακατεύθυνση εκτελείτε αν είναι απαραίτητο, ενώ οι τελεστές και οι τελεσταίοι τους αφαιρούνται από την λίστα ορισμάτων.

         Οι εντολές εκτελούνται.

         Προαιρετικά ο φλοιός αναμένει την ολοκλληρωση της εντολής και συλλέγει τη κατάσταση εξόδου.


1.4.1.2. Εντολές φλοιού

Μια απλή εντολή φλοιού όπως touch file1 file2 file3 αποτελείται από την ίδια την εντολή ακολουθούμενη από ορίσματα, χωρισμένα με κενά.

Ποιο πολύπλοκες εντολές φλοιού αποτελούνται από απλές εντολές τοποθετούμενες μαζί με διάφορες μεθόδους: σε μια σωλήνωση (pipeline) στην οποία η έξοδος μιας εντολής γίνεται η είσοδος μιας άλλης, σε μια επαναληπτική δομή ή δομή συνθήκης , ή σε κάποια άλλη ομαδοποίηση. Μερικά παραδείγματα:

ls | more

gunzip file.tar.gz | tar xvf -


1.4.1.3. Συναρτήσεις φλοιού

Οι συναρτήσεις φλοιού αποτελούν ένα τρόπο ομαδοποίησης εντολών για μελλοντική εκτέλεση χρησιμοποιώντας ένα απλό όνομα για την ομάδα. Εκτελούνται σαν μια απλή εντολή. Όταν το όνομα της διαδικασίας φλοιού χρησιμοποιείται σαν ένα απλό όνομα εντολής, η λίστα των εντολών που σχετίζεται με το όνομα της συνάρτησης εκτελείται.

Οι συναρτήσεις φλοιού εκτελούνται στα τρέχοντα συμφραζόμενα φλοιού; καμία καινούρια διεργασία δεν δημιουργείται για να τις διερμηνεύσει.

Οι συναρτήσεις εξηγούνται στο Κεφάλαιο 11.


1.4.1.4. Παράμετροι φλοιού

Η παράμετρος είναι μια οντότητα που αποθηκεύει τιμές. Μπορεί να είναι ένα όνομα, ένας αριθμός ή μια ειδική τιμή. Για τον σκοπό του φλοιού, η μεταβλητή είναι μια παράμετρος που αποθηκεύει ένα όνομα. Η μεταβλητή έχει μια τιμή και κάποια χαρακτηριστικά. Οι μεταβλητές δημιουργούνται με την εσωτερική εντολή declare.

Αν δεν δοθεί τιμή, η μεταβλητή δέχεται το κενό αλφαριθμητικό. Οι μεταβλητές μπορούν μόνο να διαγραφούν με την εσωτερική εντολή unset.

Η ανάθεση τιμών σε μεταβλητές παρουσιάζεται στην Ενότητα 3.2, η προχωρημένη χρήση των μεταβλητών στο Κεφάλαιο 10.


1.4.1.5. Επεκτάσεις φλοιού

Η επέκταση φλοιού πραγματοποιείται όταν κάθε γραμμή εντολής έχει χωριστεί σε σύμβολα (tokens). Oι επεκτάσεις που πραγματοποιούντα είναι:

         Επέκταση παρενθέσεων

         Επέκταση tilde (~)

         Επέκταση παραμέτρων και μεταβλητών

         Αντικατάσταση εντολών

         Αριθμητική επέκταση

         Διαχωρισμός λέξεων

         Επέκταση ονομάτων αρχείων

Θα συζητήσουμε αυτές τις επεκτάσεις λεπτομερειακά στην Ενότητα 3.4.


1.4.1.6. Ανακατευθύνσεις

Πριν την εκτέλεση μιας εντολής, η είσοδος και έξοδός της μπορεί να ανακατευθυνθούν χρησιμοποιώντας μια ειδική σήμανση διερμηνευμένη από τον φλοιό. Η ανακατε'υθυνση μπορεί επίσης να χρησιμοποιηθεί για άνοιγμα και κλείσιμο αρχείων στο τρέχον περιβάλλον εκτέλεσης  του φλοιού.


1.4.1.7. Εκτέλεση εντολής

Όταν εκτελείται μια εντολή, οι λέξεις που η σάρωση έχει σημειώσει σαν τιμές μεταβλητών (πριν το όνομα της εντολής,) καθώς καιι οι ανακατευθύνσεις, αποθηκεύονται για μελλοντική αναφορά. Λέξεις που δεν είναι τιμές μεταβλητών ή ανακατευθύνσεις επεκτείνονται; η πρώτη απομένουσα λέξη μετά την επέκταση λαμβάνεται ως το όνομα της εντολής και η τα υπόλοιπα ως ορίσματα σε αυτή την εντολή. Τότε λειτουργούν οι ανακατευθύνσεις,και  τα αλφαριθμητικά που έχουν θεωρηθεί τιμές μεταβλητών επεκτείνονται. Αν δεν προκύψει κάποιο όνομα εντολής, οι μεταβλητές θα επηρεάσουν το τρέχον περιβάλλον του φλοιού.

Ένα σημαντικό μέρος της εργασίας του φλοιού είναι να αναζητά εντολές. Το Bash το υλοποιεί ως εξής:

         Ελέγχει αν η εντολή περιέχει κόμματα. Αν όχι, πρώτα ελέγχει την λίστα συναρτήσεων για να δει αν περιέχει μια εντολή με το όνομα που ψάχνουμε.

         Αν η εντολή δεν είναι μια συνάρτηση, ελέγχει για αυτήν στην λίστα των εσωτερικών εντολών.

         Αν η εντολή δεν είναι συνάρτηση ή εσωτερική εντολή, τότε η αναζήτηση συνεχίζεται στους καταλόγους της μεταβλητής PATH. Το Bash χρησιμοποιεί ένα hash table (πίνακας κατακερματισμού) για να θυμάται τα πλήρη ονόματα διαδρομών των εκτελέσιμων και έτσι οι αναζητήσεις μέσω της PATH ς μππορεί να μειωθούν.

         Αν η αναζήτηση είναι ανεπιτυχής, το Bash εμφανίζει ένα μήνυμα σφάλματος και τη κατάσταση εξόδου 127.

         Αν η αναζήτηση είναι επιτυχής ή αν η εντολή περιέχει κόμματα, ο φλοιός εκτελεί την εντολή σε ξεχωριστό περιβάλλον εκτέλεσης.

         Αν η εκτέλεση αποτύχει επειδή ότι το αρχείο δεν είναι εκτελέσιμο και δεν είναι κατάλογος, τότε το Bash υποθέτει ότι είναι ένα σενάριο φλοιού.

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


1.4.1.8. Σενάρια φλοιού

Αν το Bash κληθεί με το πρώτο όρισμα μετά τις επιλογές είναι ένα όνομα αρχείου, τότε ο φλοιός υποθέτει οτι πρόκειται για σενάριο φλοιού.  (Αν κληθεί με επιλογή -c ή -s, αυτό θα δημιουργήσει έναν μη-διαλογικό φλοιό). Ο φλοιός πρώτα αναζητά το σενάριο στον τρέχοντα κατάλογο,  και αν το αρχείο δεν μπορεί να βρεθεί εκεί αναζητά το αρχέιο μέσω της PATH.


1.5. Ανάπτυξη καλών σεναρίων

1.5.1. Ιδιότητες καλών σεναρίων

Αυτός ο οδηγός αναφέρεται κυρίως στο τελευταίο δομικό μέρος του φλοιού, τα σενάρια. Μερικές γενικές σκέψεις πριν συνεχίσουμε:

1.      Ένα σενάριο θα πρέπει να εκτελέιται χωρίς λάθη.

2.      Θα πρέπει να φέρει εις πέρας τον σκοπό για τον οποίο προορίζεται.

3.      Η λογική του προγράμματος είναι αυστηρά καθορισμένη και εμφανής.

4.      Ένα σενάριο δεν κάνει δουλειά που δεν είναι απαραίτητη.

5.      Τα σενάρια πρέπει να είναι επαναχρησιμοποιήσιμα.


1.5.2. Δομή

Η δομή ενός σεναρίου φλοιού είναι πολύ ευέλικτη. Αν και στο Bash υπάρχει μεγάλη ελευθερία, πρέπει διασφαλίζεται η σωστή λογική, ο έλεγχος ροής και αποδοτικότητα έτσι ώστε οι χρήστες που εκτελούν το σενάριο να μπορούν να το κάνουν εύκολα και σωστά.

Όταν ξεκινάτε σε ένα νέο σενάριο, ρωτήστε τον εαυτό σας τις ακόλουθες ερωτήσεις:

         Θα χρειαστώ πληροφορίες από τον χρήστη ή από το περιβάλλον του χρήστη;

         Πώς θα αποθηκεύσω αυτές τις πληροφορίες;

         Υπάρχουν αρχεία που πρέπει να δημιουργηθούν; Πού και με τι άδειες και ιδιοκτησίες;

         Τι εντολές θα χρησιμοποιήσω; Όταν χρησιμοποιώ ένα σενάριο σε διαφορετικά συστήματα, έχουν όλα αυτά τα συστήματα τις εντολές στην απαραίτητη έκδοση;

         Χρειάζεται ο χρήστης κάποια πληροφορία; Πότε και γιατί;


1.5.3. Ορολογία

Ο παρακάτω πίνακας δίνει μια σύνοψη προγραμματιστικών όρων με τους οποίους πρέπει να είστε εξοικειωμένοι:

Πίνακας 1-1. Σύνοψη προγραμματιστικών όρων

Όρος

Τι είναι;

Έλεγχος εντολών

Δοκιμή της κατάστασης  εξόδου με σκοπό να εξακριβώσουμε αν το συγκεκριμένο τμήμα του προγράμματος θα εκτελεστεί σωστά

Διακλάδωση υπό συνθήκη

Λογικό σημείο στο πρόγραμμα όταν μια συνθήκη καθορίζει τι γίνεται στην συνέχεια.

Λογική ροή

Το γενικό σχέδιο του προγράμματος. ΕΚαθορίζει μια λογική ακολουθία στόχων έτσι ώστε το αποτέλεσμα να είναι επιτυχημένο και ελεγχόμενο.

Βρόχος

Μέρος του προγράμματος που εκτελείται επαναληπτικά (καμία ή περισσότερες φορές).

Είσοδος  χρήστη

Πληροφορία που παρέχεται από εξωτερική πηγή την ώρα που εκτελείται το πρόγραμμα, μπορεί να αποθηκευτεί και να ανακληθεί όταν χρειάζεται.


1.5.4. Σχόλιο για την τάξη και τη λογική

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

Μπορείτε να χρησιμοποιήσετε διάφορες μεθόδους: μια από τις ποιο συνηθισμένες είναι να δουλεύετε με λίστες. Αν δημιουργήσετε μια λίστα των εργασιών που εμπλέκονται σε ένα πρόγραμμα τότε μπορείτε να περιγράψετε καλύτερα κάθε διεργασία. Συγκεκριμένες εργασίεςστη λίστα μπορεί να αναφερθούν με τον αριθμό τους.

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

Το παρακάτω παράδειγμα δείχνει τέτοια λογική σχεδίαση. Περιγράφει την ανακύκλωση (rotation) αρχείων καταγραφής. Το παράδειγμα δείχνει μια πιθανή επαναληπτική δομή, ελεγχόμενη από τον αριθμό των αρχείων καταγραφής που θέλετε να ανακυκλώσετε:

1.      Θέλεις να  ανακυκλωσεις αρχεία καταγραφής;

a.       Αν ναι:

                                                         i.            Δώσε το όνομα διαδρομής το οποίο περιέχει τα αρχεία που θα ανακυκλωθούν.

                                                       ii.            Δώσε όνομα βάσης του αρχείου καταγραφής.

                                                      iii.            Δώσε τον αριθμό των ημερών που θα κρατηθούν τα αρχεία καταγραφής.

                                                     iv.            Κάνε μόνιμες ρυθμίσεις στο αρχείο crontab του χρήστη.

b.      Αν όχι, πήγαινε στο βήμα 3.

2.      Θέλεις να ανακυκλώσεις άλλο πακέτο αρχέιων καταγραφής;

a.       Αν ναι: επανέλαβε το βήμα 1.

b.      Αν όχι: πήγαινε στο βήμα 3.

3.      Έξοδος

Ο χρήστης θα παρέχει πληροφορίες ώστε το πρόγραμμα να κάνει κάτι. Η είσοδος από τον χρήστη πρέπει να ανακτηθεί και να αποθηκευτεί. Ο χρήστης πρέπει να ειδοποιηθεί ότι το crontab αρχείο του θα μεταβληθεί.


1.5.5. Ένα παράδειγμα σεναρίου Bash: mysystem.sh

Το σενάριο mysystem.sh εκτελεί κάποιες αρκετά γνωστές εντολές (date, w, unameuptime) για να παρουσιάσει πληροφορίες για το χρήστη και για τον υπολογιστή.

 
tom:~> cat -n mysystem.sh
     1  #!/bin/bash
     2  clear
     3  echo "This is information provided by mysystem.sh.  Program starts now."
     4
     5  echo "Hello, $USER"
     6  echo
     7
     8  echo "Today's date is `date`, this is week `date +"%V"`."
     9  echo
    10
    11  echo "These users are currently connected:"
    12  w | cut -d " " -f 1 - | grep -v USER | sort -u
    13  echo
    14
    15  echo "This is `uname -s` running on a `uname -m` processor."
    16  echo
    17
    18  echo "This is the uptime information:"
    19  uptime
    20  echo
    21
    22  echo "That's all folks!"

Ένα σενάριο πάντα ξεκινά με τους ίδιους δύο χαρακτήρες, "#!". Στην συνέχεια, στην ίδια γραμμή ορίζεται ο φλοιός που θα εκτελέσει τις εντολές που ακολουθούν. Αυτό το σενάριο ξεκινά καθαρίζοντας την οθόνη στην γραμμή 2. Η γραμμή 3 εμφανίζει ένα μήνυμα, πληροφορώντας τον χρήστη για το τι θα συμβεί. Η γραμμή 5 καλωσορίζει τον χρήστη. Οι γραμμές 6, 9, 13, 16 και 20 είναι εκεί μόνο για λόγους καλύτερης εμφάνισης των αποτελεσμάτων. Η γραμμή 8 εκτυπώνει την τρέχουσα ημερομηνία και τον αριθμό της εβδομάδας. Η γραμμή 11 είναι ξανά ένα μήνυμα πληροφόρησης, όπως οι γραμμές 3, 18 και 22. Η γραμμή 12 μορφοποιεί την έξοδο της w; η γραμμή 15 εμφανίζει το λειτουργικό σύστημα και πληροφορίες για τον επεξεργαστή. Η γραμμή 19 δίνει τις πληροφορίες της εντολής uptime.

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

Αυτό είναι το ίδιο σενάριο με χρήση της εντολής printf:

 
tom:~> cat mysystem.sh
#!/bin/bash
clear
printf "This is information provided by mysystem.sh.  Program starts now."
 
printf "Hello, $USER.\n\n"
 
printf "Today's date is `date`, this is week `date +"%V"`.\n\n"
 
printf "These users are currently connected:\n"
w | cut -d " " -f 1 - | grep -v USER | sort -u
printf "\n"
 
printf "This is `uname -s` running on a `uname -m` processor.\n\n"
 
printf "This is the uptime information:\n"
uptime
printf "\n"
 
printf "That's all folks!\n"

Η δημιουργία σεναρίων φιλικών προς τον χρήστη μέσω ενδιαφερόντων μηνυμάτων παρουσιάζεται στο Κεφάλαιο 8.

Note

Τυπική τοποθεσία του Bourne Again φλοιού

 

Υποθέτουμε ότι το πρόγραμμα bash είναι εγκατεστημένο στο /bin.

Warning

Αν η πρότυπη έξοδος (stdout) δεν είναι διαθέσιμη

 

Αν εκτελείτε ένα σενάριο από το cron, θα πρέπει να δίνετε πλήρη ονόματα διαδρομών και να ανακατευθύνετε τη πρότυπη έξοδο και το πρότυπο σφάλμα (stdout και stderr). Αν δεν το έχουμε σκεφτεί, οποιαδήποτε λάθη αναγκάζουν το σενάριο να τερματίσει πρόωρα, αφού ο φλοιός εκτελείται σε μη-διαλογική κατάσταση, .

Το κεφάλαιο που ακολουθεί θα παρουσιάσει λεπτομερώς τα παραπάνω σενάρια.


1.5.6. Παράδειγμα σεναρίου εκκίνησης (init)

Ένα σενάριο εκκίνησης σε συστήματα UNIX και Linux ξεκινά τις υπηρεσίες του συστήματος. Ο δαίμονας καταγραφής συστήματος, ο δαίμονας διαχείρισης ισχύος, οι δαίμονες ονομασίας και αλληλογραφίας είναι συνηθισμένα παραδείγματα. Αυτά τα σενάρια, επίσης γνωστά και ως σενάρια αρχικοποίησης, είναι αποθηκευμένα σε μια συγκεκριμένη τοποθεσία στο σύστημά σας, όπως /etc/rc.d/init.d ή /etc/init.d. Η init, αρχική διεργασία, διαβάζει τα αρχεία ρυθμίσεών της της και αποφασίζει ποιες υπηρεσίες να εκκινήσει ή να τερματίσει σε κάθε επίπεδο εκτέλεσης (runlevel). Το επίπεδο εκτέλεσης είναι μια συνολική ρύθμιση των διεργασιών που εκκινούν μαζί με το σύστημα. Κάθε σύστημα έχει ένα επίπεδο εκτέλεσης απλού χρήστη, για παράδειγμα, για να φέρει εις πέρας εργασίες διαχείρισης, για τις οποίες το σύστημα πρέπει να είναι σε μια όσο το δυνατόν αδρανή κατάσταση, όπως λόγου χάρη κατά την επανάκτηση ενός κρίσιμου αρχείου συστήματος από εφεδρικά αντίγραφα. Συνήθως τα επίπεδα εκτέλεσης της επανεκκίνησης και του τερματισμού είναι επίσης προ-ρυθμισμένα.

Οι εργασίες που πρέπει να εκτελεστούν κατά την εκκίνηση ή τερματισμό μιας υπηρεσίας καταγράφονται στο αντίστοιχο σενάριο εκκίνσης. Μια από τις βασικές εργασίες διαχείρισης συστήματος είναι η διαμόρφωση της init, έτσι ώστε ο σωστές υπηεσίες να εκκινούν ή να τερματίζονται στο σωστό χρόνο. Η δουλειά αυτή απαιτεί κατανόηση των διαδικασιών εκκίνησης και τερματισμού του συστήματος. Σας συμβουλεύουμε να διαβάσετε τις σελίδες του εγχειριδίου για την init και το inittab πριν ασχοληθείτε με τα σενάρια εκκίνησης.

Εδώ είναι ένα πολύ απλό παράδειγμα, που παράγειι έναν ήχο κατά την εκκίνηση και τον τερματισμό του υπολογιστή:

 
#!/bin/bash
 
# This script is for /etc/rc.d/init.d
# Link in rc3.d/S99audio-greeting and rc0.d/K01audio-greeting
 
case "$1" in
'start')
  cat /usr/share/audio/at_your_service.au > /dev/audio
  ;;
'stop')
  cat /usr/share/audio/oh_no_not_again.au > /dev/audio
  ;;
esac
exit 0

Η εντολή case χρησιμοποιείταισυχνά σε τέτοιου είδους σενάρια και περιγράφεται στην Ενότητα 7.2.5.


1.6. Περίληψη

Το Bash είναι ο GNU φλοιός, συμβατός με τον Bourne φλοιό και ενσωματώνει πολλά χρήσιμα χαρακτηριστικά άλλων φλοιών. Όταν ο φλοιός ξεκινάει, διαβάζει τα αρχεία ρύθμισής του. Τα ποιο σημαντικά είναι:

         /etc/profile

         ~/.bash_profile

         ~/.bashrc

Το Bash συμπεριφέρεται διαφορετικά όταν διαλόγική ή μη-διαλογική κατάσταση και επίσης παρέχει μια περιορισμένη κατάσταση POSIX - συμβατότητας.

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

Τα σενάρια φλοιού αποτελούνται από τέτοιες εντολές οργανωμένες με βάση το συντακτικό του φλοιού. Τα σενάριαδιαβάζονται και εκτελούνται ακολουθιακά και πρέπει να έχουν μια λογική δομή.


1.7. Ασκήσεις

Μερικές ασκήσεις που θα σας προετοιμάσουν για το επόμενο κεφάλαιο:

1.      Σε ποιο σημείο του συστήματός σου βρίσκεται το πρόγραμμα bash;

2.      Χρησιμοποιήστε την επιλογή --version για να μάθετε ποια έκδοση έχετε.

3.      Ποια αρχεία ρύθμισης φλοιού διαβάζονται όταν συνδέεστε στο σύστημά σας χρησιμοποιώντας την γραφική διεπαφή χρήστη και μετά ανοίγετε ένα παράθυρο τερματικού;

4.      Είναι οι ακόλουθοι φλοιοί διαλογικοί; Είναι φλοιοί σύνδεσης;

o        Ένας φλοιός που ανοίγει κάνοντας κλικ στο υπόβαθρο της γραφικής σου επιφάνειας εργασίας ή επιλέγοντας "Τερματικόl" ή κάτι τέτοιο από ένα μενού.

o        Ένας φλοιός που λαμβάνετε μόλις εισάγετε την εντολή ssh localhost.

o        Ένας φλοιός που λαμβάνετε όταν συνδέεστε στο σύστημα σε κατάσταση κειμένου.

o        Ένας φλοιός που αποκτάται με την εντολή xterm &.

o        Ένας φλοιός που ανοίγει με το σενάριο mysystem.sh.

o        Ένας φλοιός που λαμβάνετε από απομακρυσμένη είσοδο, για την οποία δεν χρειάστηκε να δώσετε το όνομα  χρήστη και/ ή τον κωδικό πρόσβασης επειδή χρησιμοποιείτε SSH και ίσως SSH κλειδιά.

5.      Μπορείτε να εξηγήσετε γιατί το bash δεν τερματίζεται όταν πληκτρολογείτε Ctrl+C στην γραμμή εντολών;

6.      Εμφάνισε το περιεχόμενο της στοίβας καταλόγων.

7.      Αν δεν είναι ήδη έτσι ρυθμισμένη, ρυθμίστε την προτροπής σας ώστε να εμφανίζει τον τρέχοντα κατάλογό σας, για παράδειγμα πρόσθεσε αυτή τη γραμμή στο ~/.bashrc:

export PS1="\u@\h \w> "

8.      Εμφάνισε hashed εντολές για την τρέχουσα σύνοδο του φλοιού σας.

9.      Πόσες διεργασίες εκτελούνται στο σύστημά σας; Χρησιμοποίησε τις ps και wc, η πρώτη γραμμή εξόδου της ps δεν είναι διεργασία!

10.  Πώς θα εμφανίσετε το όνομα του συστήματος; Μόνο το όνομα, τίποτα άλλο!


Κεφάλαιο 2. Συγγραφή και εκσφαλμάτωση σεναρίων

Μόλις τελειώσετε αυτό το κεφάλαιο θα μπορείτε:

         Να γράψετε ένα απλό σενάριο.

         Να ορίσετε τον τύπο του φλοιού που πρέπει να εκτελέσει το σενάριο

         Να τοποθετήσετε σχόλια στον κώδικα των σεναρίου σας.

         Να αλλάξετε τις άδειες προσπέλασης ενός σεναρίου.

         Να εκτελέσετε και να εκσφαλματώσετε ένα σενάριο.


2.1. Δημιουργία και εκτέλεση ενός σεναρίου

2.1.1. Συγγραφή και ονομασία

Ένα σενάριο φλοιού είναι μια ακολουθία εντολών τις οποίες χρησιμοποιείτε κατ' επανάληψη. Αυτή η ακολουθία τυπικά εκτελείται εισάγοντας το όνομα του σεναρίου στην γραμμή εντολών. Εναλλακτικά, μπορείτε να χρησιμοποιείτε σενάρια για να αυτοματοποιήσετε διαδικασίες χρησιμοποιώντας την υπηρεσία cron. Μια άλλη χρήση σεναρίων είναι η διαδικασία εκκίνησης και τερματισμού του UNIX, όπου οι  λειτουργίες των δαιμόνων και  των υπηρεσιών ορίζονται με τα σενάρια εκκίνσης.

Για να δημιουργήσετε ένασενάριο φλοιού, ανοίξτε ένα καινούργιο άδειο αρχείο σε ένα συντάκτη κειμένου. Οποιοσδήποτε συντάκτης αρκεί:  vim, emacs, gedit, dtpad κλπ είναι όλοι έγκυροι. Ίσως όμως θελήσετε να χρησιμοποιήσετε ένα πιο προχωρημένο συντάκτη όπως ο vim ή ο emacs, γιατί αυτοί μπορούν να ρυθμιστούν να αναγνωρίζουν τη σύνταξη του φλοιού Bash και μπορούν να αποτελέσουν πολύτιμη βοήθεια αποτρέποντας λάθη που οι αρχάριοι κάνουν συχνά, όπως να παράλειψη παρενθέσεων και τερματικών συμβόλων.

Τοποθετήστε εντολές UNIX σε ένα καινούργιο άδειο αρχείο, σαν να τις γράφατε στην γραμμή εντολών. Όπως συζητήθηκε στο προηγούμενο κεφάλαιο, (δείτε Ενότητα 1.3), οι εντολές μπορεί να είναι συναρτήσεις φλοιού, εσωτερικές εντολές φλοιού, εντολές του UNIX και άλλα σενάρια.

Δώστε στο σενάριό σας ένα λογικό όνομα που να δίνει μια ιδέα σχετικά με το τι κάνει. Σιγουρευτείτε ότι το όνομα του σεναρίου σας δεν είναι ίδιο με κάποιο από τα υπάρχοντα αρχεία. Για να σιγουρευτείτε ότι δεν μπορεί να υπάρξει σύγχυση, τα ονόματα των σεναρίων συχνά τελειώνουν σε .sh. Ακόμη και έτσι, μπορούν να υπάρχουν και άλλα σενάρια στο σύστημα σας με το ίδιο όνομα που διαλέξατε. Σιγουρευτείτε κάνοντας χρήση των εντολών which, whereis και άλλων εντολές για την αναζήτηση προγραμμάτων και αρχείων: 

which -a script_name

whereis script_name

locate script_name


2.1.2. script1.sh

Σε αυτό το παράδειγμα χρησιμοποιούμε την εσωτερική εντολή echo για να ενημερώσουμε τον χρήστη για το τι πρόκειται να συμβεί, πρίν εκτελεστεί η εντολή που θα δημιουργήσει το αποτέλεσμα  Καλό είναι να ενημερώνετε τους χρήστες σχετικά με την λειτουργία των εντολών, για να τους αποτρέψετε να γίνουν νευρικοί πιστεύοντας ότι το σενάριο δεν κάνει τίποτα. Θα επιστρέψουμε στο θέμα αυτό (ενημέρωση χρηστών) στο Κεφάλαιο 8.

Εικόνα 2-1. script1.sh

Εικόνα 2-1

Γράψτε αυτό το σενάριο μόνοι σας. Είναι καλή ιδέα να δημιουργήσετε ένα κατάλογο ~/scripts όπου να αποθηκεύετε τα σενάριά σας. Προσθέστε αυτόν το κατάλογο στη μεταβλητή PATH :

export PATH="$PATH:~/scripts"

Αν είστε καινούργιοι στο Bash, χρησιμοποιήστε έναν συντάκτη κειμένου που χρησιμοποιεί διαφορετικά χρώματα για τις διαφορετικές δομές. Χρωματική υποβοήθη υποστηρίζουν οι vim, gvim, (x)emacs, kwrite, gedit και πολλοί άλλοι συντάκτες, ελέγξτε τη σχετική τεκμηρίωση.

Note

Διαφορετικές προτροπές

Οι προτροπές στο εγχειρίδιο μπορεί να αλλάζουν ανάλογα με την διάθεση του συγγραφέα. Αυτό αντιπροσωπεύει πιο πολύ πραγματικές καταστάσεις απο το εκπαιδευτικό σύμβολο προτροπής $. Η μόνη σύμβαση που χρησιμοποιούμε είναι ότι η προτροπή root τελειώνει με ένα hash (#).


2.1.3. Εκτέλεση του σεναρίου

Το σενάριο για να μπορεί να εκτελεστεί πρέπει να παρέχει δικαιώματα εκτέλεσης στους σωστούς χρήστες. Όταν ορίζετε τα δικαιώματα, σιγουρευτείτε ότι πραγματικά αποκτήσατε τα δικαιώματα που επιθυμούσατε. Όταν αυτό ολοκληρωθεί, το σενάριο μπορεί να εκτελεστεί όπως μια κοινή εντολή:

 
willy:~/scripts> chmod u+x script1.sh
 
willy:~/scripts> ls -l script1.sh
-rwxrw-r--    1 willy  willy          456 Dec 24 17:11 script1.sh
 
willy:~> script1.sh
The script starts now.
Hi, willy!
 
I will now fetch you a list of connected users:
 
3:38pm  up 18 days,  5:37,  4 users,  load average: 0.12, 0.22, 0.15
USER  	TTY      FROM         LOGIN@   IDLE   JCPU   PCPU  WHAT
root 	tty2 	 -             Sat 2pm  4:25m  0.24s  0.05s  -bash
willy   :0	 -             Sat 2pm   ?     0.00s   ?     -
willy   pts/3    -             Sat 2pm  3:33m 36.39s 36.39s  BitchX willy ir
willy   ts/2     -             Sat 2pm  3:33m  0.13s  0.06s  /usr/bin/screen
 
I'm setting two variables now.
This is a string: black
And this is a number: 9
 
I'm giving you back your prompt now.
 
willy:~/scripts> echo $COLOUR
 
willy:~/scripts> echo $VALUE
 
willy:~/scripts>

Αυτός είναι ο πιο συνηθισμένος τρόπος εκτέλεσης ενός σεναρίου. Ένα τέτοιο σενάριο είναι προτιμότερο να εκτελεστεί σε ένα υποφλοιό. Οι μεταβλητές, οι λειτουργίες, και τα ψευδώνυμα που δημιουργούνται σε αυτόν τον υποφλοιό είναι γνωστά μόνο στην συγκεκριμένη χρήση του υποφλοιού. 'Οταν αυτός ο φλοιός τερματιστεί και ο γονικός φλοιός επανέλθει στο προσκήνιο, τα πάντα καθαρίζονται και όλες οι αλλαγές στην κατάσταση του φλοιού που έγιναν απο το σενάριο, διαγράφονται.

Αν δεν έχετε βάλει τον κατάλογο scripts στο PATH, και το . (ο τρέχων κατάλογος) δεν βρίσκεται και αυτός στο PATH, ενεργοποιείτε στο σενάριο ως εξής:

./script_name.sh

Επίσης, ένα σενάριο μπορεί να εκτελεστεί ρητά με ένα δεδομένο φλοιό, αλλά γενικά αυτό το κάνουμε αν θέλουμε να πετύχουμε κάτι συγκεκριμένο,  όπως να σιγουρευτούμε αν το σενάριο δουλεύει με ένα άλλο φλοιό ή να εμφανίσουμε ίχνη για εκσφαλμάτωση:

rbash script_name.sh

sh script_name.sh

bash -x script_name.sh

Ο επιλεγμένος φλοιός θα ξεκινήσει σαν ένας υποφλοιόςς του τρέχοντος λοιού και θα εκτελέσει το σενάριο. Αυτό γίνεται όταν θέλετε το σενάριο να ξεκινήσει με συγκεκριμένες επιλογές ή κάτω από συγκεκριμένες καταστάσεις που δεν προσδιορίζονται στοσενάριο.

Εάν δεν θέλετε να ξεκινήσει ένας καινούργιος φλοιός αλλά να εκτελέσετε το σενάριο στον τρέχοντα φλοιό, χρησιμοποιείστε την εντολή source:

source script_name.sh

Tip

source = .

Η ενσωματωμένη εντολή source του Bash είναι συνώνυμι της εντολής  . (dot).

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

 
willy:~/scripts> source script1.sh
--output ommitted--
 
willy:~/scripts> echo $VALUE
9
 
willy:~/scripts>

2.2. Τα βασικά των σεναρίων

2.2.1. Ποιός φλοιός θα εκτελέσει το σενάριο;

Όταν εκτελείιτε ένα σενάριο σε ένα υποφλοιό, πρέπει να ορίσετε με ποιό φλοιό θα εκελεστεί. Ο τύπος του φλοιού στον οποίο γράψατε το σενάριο μπορεί να μην είναι ο προεπιλεγμένος στο σύστημα σας, και έτσι οι εντολές που εισάγατε μπορεί να οδηγήσουν σε λάθη όταν εκτελούνται από λάθος φλοιό.

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

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

#!/bin/bash

Όπως σημειώθηκε προηγούμενα, αυτό υπονοεί ότι το εκτελέσιμο του Bash βρίσκεται στο /bin.


2.2.2. Προσθήκη σχολίων

Πρέπει να καταλάβετε ότι πολλές φορές δεν θα είστε οι μοναδικοί που διαβάζετε τον κώδικά σας. Πολλοί χρήστες και διαχειριστές συστημάτων εκτελούν σενάρια που είναι γραμμένα από άλλους. Αν κάποιος θελήσει να μελετήσει  ένα σενάριο, τα σχόλια είναι χρήσιμα για να κατατοπίσουν τον αναγνώστη.

Επίσης, τα σχόλια κάνουν την ζωή σας πιο εύκολη. Ας πούμε ότι χρειάστηκε να διαβάσετε πολλές σελίδες για να πετύχετε ένα συγκεκριμένο αποτέλεσμα με κάποια εντολή που χρησιμοποιήσατε στο σενάριό σας. Αν χρειαζόταν να αλλάξετε το σενάριό σας μετά από  μερικές εβδομάδες ή μήνες, και δεν έχετε σχολιάσει τον κώδικα σας σχετικά με το τι κάνατε, πώς το κάνατε, και γιατί το κάνατε, πιθανότατα δεν θα θυμάστε πως τα καταφέρατε. 

Πάρτε το παράδειγμα του script1.sh και αντιγράψτε το σε commented-script1.sh, το οποίο θα αλλάξουμε έτσι ώστε τα σχόλια να αντικατοπτρίζουν την λειτουργία του. Οτιδήποτε βρίσκεται μετά το hash αγνοείται μετά το άνοιγμα του αρχείου:

 
#!/bin/bash
# This script clears the terminal, displays a greeting and gives information
# about currently connected users.  The two example variables are set and displayed.
 
clear                          # clear terminal window
 
echo "The script starts now."
 
echo "Hi, $USER!"              # dollar sign is used to get content of variable
echo
 
echo "I will now fetch you a list of connected users:"
echo                                                 
w                              # show who is logged on and
echo                           # what they are doing
 
echo "I'm setting two variables now."
COLOUR="black"                                # set a local shell variable
VALUE="9"                                     # set a local shell variable
echo "This is a string: $COLOUR"              # display content of variable 
echo "And this is a number: $VALUE"           # display content of variable
echo
 
echo "I'm giving you back your prompt now."
echo

Σε ένα αξιοπρεπές σενάριο, οι πρώτες γραμμές είναι συνήθως σχόλια σχετικά με το τι να περιμένουμε. Επίσης κάθε ομάδα εντολών πρέπει να σχολιαστεί για λόγους κατανόησης του σεναρίου. Τα σενάρια εκκίνησης του Linux, για παράδειγμα, στον κατάλογο init.d , συχνά σχολιάζονται συστηματικά αφού πρέπει να είναι κατανοητά και τροποποιήσιμα από οποιονδήποτε εκτελεί Linux.


2.3. Εκσφαλμάτωση σεναρίων Bash 

2.3.1. Εκσφαλμάτωση ολόκληρου σεναρίου

Όταν τα πράγματα δεν πηγαίνουν όπως περιμένουμε, πρέπει είμαστε σε θέση να καταλάβουμε τι ακριβώς δεν πήγε καλά. Το Bash παρέχει πολλά χαρακτηριστικά  που βοηθούν στην εκσφαλμάτωση. Το πιο συνηθισμένο είναι να ξεκινήσουμε τον υποφλοιό με την επιλογή -x, η οποία θα εκτελέσει ολόκληρο το σενάριο σε κατάσταση εκσφαλμάτωσης. Τα ίχνη της κάθε εντολής μαζί με τα ορίσματα της εμφανίζονται στην πρότυπη έξοδο (stdout) αφότου οι εντολές έχουν επεκταθεί αλλά πριν εκτελεστούν.

Αυτό είναι το σενάριο commented-script1.sh  που εκτελέιται σε κατάσταση εκσφαλμάτωσης. Σημειώστε ξανά ότι τα σχόλια δεν είναι ορατά στα αποτελέσματα του σεναρίου.

 
willy:~/scripts> bash -x script1.sh
+ clear
 
+ echo 'The script starts now.'
The script starts now.
+ echo 'Hi, willy!'
Hi, willy!
+ echo
 
+ echo 'I will now fetch you a list of connected users:'
I will now fetch you a list of connected users:
+ echo
 
+ w
  4:50pm  up 18 days,  6:49,  4 users,  load average: 0.58, 0.62, 0.40
USER     TTY      FROM           LOGIN@   IDLE   JCPU   PCPU  WHAT
root     tty2     -              Sat 2pm  5:36m  0.24s  0.05s  -bash
willy    :0       -              Sat 2pm   ?     0.00s   ?     -
willy    pts/3    -              Sat 2pm 43:13  36.82s 36.82s  BitchX willy ir
willy    pts/2    -              Sat 2pm 43:13   0.13s  0.06s  /usr/bin/screen
+ echo
 
+ echo 'I'\''m setting two variables now.'
I'm setting two variables now.
+ COLOUR=black
+ VALUE=9
+ echo 'This is a string: '
This is a string:
+ echo 'And this is a number: '
And this is a number:
+ echo
 
+ echo 'I'\''m giving you back your prompt now.'
I'm giving you back your prompt now.
+ echo

 

Note

Νέα χαρακτηριστικά Bash 

Από την έκδοση bash-3.0 και μεταγενέστερα το Bash περιλαμβάνει ένα ενισχυμένο σύστημα εκσφαλμάτωσης. Για παλιότερες εκδόσεις, ανώτερες του bash-2.05, διατίθεται αντίστοιχο patch στο SourceForge


2.3.2. Εκσφαλμάτωση τμημάτων του σεναρίου

Με την εντολή setτου Bash, μπορείτε να εκτελέσετε σε κανονική κατάσταση εκείνα τα τμήματα του σεναρίου, για τα οποία είστε σίγουρος ότι λειτουργούν χωρίς πρόβλημα, και να εμφαμίσετε πληροφορίες εκσφαλμάτωσης μόνο για τα προβληματικά τμήματα. Έστω ότι δεν είμαστε σίγουροι για το τι θα κάνει η εντολή w στο παράδειγμα commented-script1.sh, τότε μπορούμε να  προσθέσουμε στπ σενάριο κάτι σαν και αυτό:

 
set -x                  # activate debugging from here
w
set +x                 # stop debugging from here

Η έξοδος θα είναι κάπως έτσι:

 
willy: ~/scripts> script1.sh
The script starts now.
Hi, willy!
 
I will now fetch you a list of connected users:
 
+ w
  5:00pm  up 18 days,  7:00,  4 users,  load average: 0.79, 0.39, 0.33
USER     TTY      FROM          LOGIN@   IDLE   JCPU   PCPU  WHAT
root     tty2     -             Sat 2pm  5:47m  0.24s  0.05s  -bash
willy    :0       -             Sat 2pm   ?     0.00s   ?     -
willy    pts/3    -             Sat 2pm 54:02  36.88s 36.88s  BitchX willyke
willy    pts/2    -             Sat 2pm 54:02   0.13s  0.06s  /usr/bin/screen
+ set +x
 
I'm setting two variables now.
This is a string:
And this is a number:
 
I'm giving you back your prompt now.
 
willy: ~/scripts>

Μπορείτε να ενεργοποιήσετε και να απενεργοποιήσετε την κατάσταση εκσφαλμάτωσης όσες φορές θέλετε μέσα στο ίδιο σενάριο.

Ο παρακάτω πίνακας δίνει μία σύνοψη άλλων χρήσιμων εντολών εκσφαλμάτωσης για το Bash:

Πίνακας 2-1. Επισκόπηση των επιλογών εκσφαλμάτωσης της εντολής set 

Σύντομη γραφή

Ανεπτυγμένη γραφή

Αποτέλεσμα

set -f

set -o noglob

Απενεργοποιεί τη δημιουργία ονομάτων αρχείων με χρήση μεταχαρακτήρων (globbing).

set -v

set -o verbose

Εμφανίζει τις γραμμές εισόδου του φλοιού μόλις διαβάζονται.

set -x

set -o xtrace

Εμφανίζει τα ίχνη των εντολών πριν εκτελεστούν.

Η παύλα σημαίνει ενεργοποίηση της επιλογής και το συν σημαίνει απενεργοποίηση. Προσοχή μην μπερδευτείτε!

Στο παρακάτω παράδειγμα, επιδεικνύουμε τις επιλογές στη γραμμή εντολών:

 
willy:~/scripts> set -v
 
willy:~/scripts> ls
ls 
commented-scripts.sh   script1.sh
 
willy:~/scripts> set +v
set +v
 
willy:~/scripts> ls *
commented-scripts.sh    script1.sh
 
willy:~/scripts> set -f
 
willy:~/scripts> ls *
ls: *: No such file or directory
 
willy:~/scripts> touch *
 
willy:~/scripts> ls
*   commented-scripts.sh    script1.sh
 
willy:~/scripts> rm *
 
willy:~/scripts> ls
commented-scripts.sh    script1.sh

Εναλλακτικά, αυτές οι καταστάσεις μπορούν να προσδιοριστούν μέσα στο ίδιο το σενάριο, τοποθετώντας τις επιλογές που θέλετε στην πρώτη γραμμή δήλωσης του φλοιού. Οι επιλογές μπορούν να συνδιαστούν, όπως συμβαίνει συνήθως με τις εντολές UNIX:

#!/bin/bash -xv

Μόλις βρείτε το προβληματικό τμήμα του σεναρίου, μπορείτε να τοποθετήσετε εντολές echo πριν από κάθε εντολή για την οποία δεν είστε βέβαιοι, και έτσι θα μπορέσετε να βρείτε ακριβώς σε ποιό σημείο τα πράγματα δεν δούλεψαν. Στο παράδειγμα του σεναρίου commented-script1.sh, υποθέτοντας ότι η εμφάνιση των χρηστών δημιουργεί πρόβλημα, μπορούμε να έχουμε:

echo "debug message: now attempting to start w command"; w

Σε πιο προχωρημένα σενάρια, η εντολή echo μπορεί να χρησιμοποιηθεί για την εμφάνιση του περιεχομένου (της τιμής) μεταβλητών σε διάφορα στάδια εκτέλεσης του σεναρίου και τον εντοπισμό λαθών:

 
echo "Variable VARNAME is now set to $VARNAME."

2.4. Περίληψη

Ένα σενάριο φλοιού είναι μία επαναχρησιμοποιήσιμη σειρά εντολών οποθετημένων σε ένα εκτελέσιμο αρχείο κειμένου. Οποιοσδήποτε συντάκτης κειμένου μπορεί να χρησιμοποιηθεί για τη συγγραφή σεναρίων.

Τα σενάρια αρχίζουν με #! και ακολουθεί η διαδρομή προς τον φλοιό που εκτελεί τις εντολές από το σεναρίου. Τα σχόλια προστίθενται σε ένα σενάριο για την δική σας μελλοντική αναφορά, όπως επίσης και για να είναι κατανοητός ο κώδικάς σας από άλλους. Είναι καλύτερο να συμπεριλάβετε πολλές εξηγήσεις από το να μην συμπεριλάβετε καθόλου.

Η εκσφαλμάτωση ενός σεναρίου μπορεί να γίνει με την χρήση επιλογών του φλοιού. Οι επιλογές του φλοιού μπορούν να χρησιμοποιηθούν για μερική αποσφαλμάτωση ή για την ανάλυση ολόκληρου του σεναρίουt. Η εισαγωγή των εντολών echo σε στρατηγικά σημεία στον κώδικά σας είναι μια  συνιθισμένη τεχνική που λύνει πολλά προβλήματα.


2.5. Ασκήσεις

Αυτές οι ασκήσεις θα σας βοηθήσουν να δημιουργήσετε το πρώτο σας σενάριο.

1.      Γράψτε άνα σενάριο με τη βοήθεια του συντάκτη κειμένου που προτιμάτε. Το σενάριο πρέπει να εμφανίζει τη διαδρομή για τον οικείο σας κατάλογο και τον τύπο τερματικού που χρησιμοποιείτε. Επίσης εμφανίζει όλες τις υπηρεσίες που ξεκινούν στο επίπεδο εκτέλεσης 3 του συστήματός σας (υπόδειξη: χρησιμοποιείστε τα HOME, TERM and ls /etc/rc3.d/S*)

2.      Προσθέστε σχόλια στο σενάριό σας.

3.      Προσθέστε πληροφορίες για τους χρήστες του σεναρίου σας.

4.      Αλλάξτε τις άδειες προσπέλασης του σεναρίου για να μπορέσετε να το εκτελέσετε.

5.      Εκτελέστε το σενάριο σε κανονική κατάσταση και σε κατάσταση εκσφαλμάτωσης. Πρέπει να εκτελείται χωρίς σφάλματα.

6.      Κάντε μερικά λάθη στο σενάριό σας: Δείτε τι συμβαίνει αν γράψετε λάθος μερικές εντολές, αν παραλείψετε την πρώτη γραμμή ή τοποθετήστε κάτι μη αναγνώσιμο εκεί, ή αν γράψετε λανθασμένα ονόματα μεταβλητών του κελύφους ή αν γράψετε λάθος ονόματα μεταβλητών του κελύφους π.χ. με μικρά γράμματα ενώ έχουν δηλωθεί με κεφαλαία. Ελέγξτε τα σχόλια της εκσφαλμάτωσης σχετικά με αυτά τα λάθη.


Κεφάλαιο 3. Το περιβάλλον Bash

Σε αυτό το κεφάλαιο θα συζητήσουμε διάφορους τρόπους με τους οποίους επηρεάζεται το περιβάλλον Bash :

         Τροποποίηση των αρχείων ρύθμισης

         Χρήση μεταβλητών

         Χρήση διαφόρων τύπων εισαγωγικών

         Εκτέλεση αριθμητικών υπολογισμών

         Ορισμός ψευδωνύμων

         Χρήση επέκτασης και αντικατάστασης


3.1. Αρχεία ρύθμισης φλοιού

3.1.1. Αρχεία ρύθμισης για όλο το σύστημα

3.1.1.1. /etc/profile

Όταν το Bash καλείται διαλογικά με την επιλογή  --login ή  όταν καλέιται με την εντολή sh, τότε διαβάζει τις ρυθμίσεις στο αρχείο /etc/profile. Αυτές συνήθως  θέτουν τις μεταβλητές φλοιού PATH, USER, MAIL, HOSTNAME and HISTSIZE.

Σε μερικά συστήματα, η τιμή umask ρυθμίζεται στο /etc/profile. Σε άλλα συστήματα αυτό το αρχείο διατηρεί δείκτες σε άλλα αρχεία διαμόρφωσης όπως τα:

         /etc/inputrc, ένα αρχείο ρύθμισης της Readline για όλο το σύστημα όπου μπορείτε να διαμορφώσετε το στυλ της γραμμής εντολών.

         /etc/profile.d ένας κατάλογος, που περιέχει αρχεία ρύθμισης για όλο το σύστημα σχετικά με τη συμπεριφορά των ειδικών προγραμμάτων.

Όλες οι ρυθμίσεις που θέλετε να εφαρμόσετε σε όλα τα περιβάλλοντα των χρηστών σας πρέπει να είναι σε αυτό το αρχείο. Μπορεί να μοιάζει με αυτό:

# /etc/profile
 
# System wide environment and startup programs, for login setup
 
PATH=$PATH:/usr/X11R6/bin
 
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
 
USER="`id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
 
HOSTNAME=`/bin/hostname`
HISTSIZE=1000
 
# Keyboard, bell, display style: the readline config file:
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
    INPUTRC=/etc/inputrc
fi
 
PS1="\u@\h \W"
 
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC PS1
 
# Source initialization files for specific programs (ls, vim, less, ...)
for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
        . $i
    fi
done
 
# Settings for program initialization
source /etc/java.conf
export NPX_PLUGIN_PATH="$JRE_HOME/plugin/ns4plugin/:/usr/lib/netscape/plugins"
 
PAGER="/usr/bin/less"
 
unset i

Αυτό το αρχείο διαμόρφωσης θέτει μερικές βασικές μεταβλητές περιβάλλοντος φλοιού καθώς επίσης και μερικές μεταβλητές απαιτούμενες για χρήστες που εκτελούν την Java ή/και τις εφαρμογές της Java στον περιηγητή Ιστού τους. Δείτε την Ενότητα 3.2.

Δείτε το Κεφάλαιο 7 για περισσότερα στχοιχεία σχετικά με την χρήση του if σε αυτό το αρχείο. Το Κεφάλαιο 9 συζητά τους βρόχους όπως αυτός στη δομή for

Ο πηγαίος κώδικας του Bash περιέχει δείγματα από αρχεία profile για γενική και ατομική χρήση. Τόσο αυτά όσο και το παραπάνω παράδειγμα χρειάζονται τροποποιήσιεις για να δουλέψουν στο περιβάλλον σας!


3.1.1.2. /etc/bashrc

Τα συστήματα προσφέρουν πολλαπλούς τύπους φλοιών, θα ήταν καλό να βάλουμε ειδικές ρυθμίσεις του Bash σε αυτό το αρχείο, αφού το /etc/profile διαβάζεται και από άλλους φλοιούς, όπως ο φλοιός Bourne. Με τον διαχωρισμό τον αρχείων ρύθμισης για διαφορετικούς τύπους φλοιών αποφεύγουμε τα λάθη που προκαλούνται από τους φλοιούς που δεν αντιλαμβάνονται  το συντακτικό του φλοιού Bash. Σε τέτοιες περιπτώσεις, το αρχείο ~/.bashrc του χρήστη μπορεί να οδηγεί στο αρχείο /etc/bashrc για να το συμπεριλάβει στην διαδικασία αρχικοποίησης του φλοιού κατά τη σύνδεση.

Επίσης μπορεί να βρείτε ότι το /etc/profile στο σύστημά σας διατηρεί μόνο αρχικές ρυθμίσεις περιβάλλοντος του φλοιού, ενώ το /etc/bashrc περιέχει τους ρυθμίσεις για όλο το σύστημα για τις λειτουργίες του φλοιού και των ψευδωνύμων. Το αρχείο /etc/bashrc ίσως να αναφέρεται μέσα στο /etc/profile ή μέσα στα ατομικά αρχεία ρυμισης φλοιού του κάθε χρήστη.

Ο πηγαίος κώδικας του Bash περιέχει παραδείγματα αρχείων bashrc, ή μπορείτε να βρείτε ένα αντίγραφο στο /usr/share/doc/bash-2.05b/startup-files. Αυτό είναι ένα μέρος από το bashrc το οποίο συνοδεύει την τεκμηρίωση του φλοιού Bash:

 
alias ll='ls -l'
alias dir='ls -ba'
alias c='clear'
alias ls='ls --color'
 
alias mroe='more'
alias pdw='pwd'
alias sl='ls --color'
 
pskill()
{
        local pid
 
        pid=$(ps -ax | grep $1 | grep -v grep | gawk '{ print $1 }')
        echo -n "killing $1 (process $pid)..."
        kill -9 $pid
        echo "slaughtered."
}
 

Εκτός από γενικά ψευδώνυμα, περιέχει χρήσιμα ψευδώνυμα που επιτρέπουν τη λειτουργία ορισμένων εντολών ακόμη και όταν τις γράφετε λάθος. Θα συζητήσουμε τα ψευδώνυμα και στην Ενότητα 3.5.2. Το αρχείο περιέχει και μια συνάρτηση, τη pskill. Οι συναρτήσεις θα συχητηθούν στο Κεφάλαιο 11.


3.1.2. Ατομικά αρχεία ρύθμισης χρηστών

Note

Δεν έχω τέτοια αρχεία;!

αυτά τα αρχεία μπορεί να μην βρίσκονται ως προεπιλογή στον οικείο σας κατάλογο. Αν χρειάζεται, δημιουργείστα τα.


3.1.2.1. ~/.bash_profile

Αυτό είναι το προτιμώμενο αρχείο για τη εξατομικευμένη διαμόρφωση των περιβάλλοντος των χρηστών. Σε αυτό το αρχείο, οι χρήστες μπορούν να προσθέσουν επιλογές ρύθμισης ή να αλλάξουν τις προκαθορισμένες ρυθμίσεις:

 
franky~> cat .bash_profile
#################################################################
#                                                               #
#   .bash_profile file                                          #
#                                                              	#
#   Executed from the bash shell when you log in.               #
#                                                               #
#################################################################
 
source ~/.bashrc
source ~/.bash_login
case "$OS" in
  IRIX)
    stty sane dec
    stty erase
    ;;
#  SunOS)
#  stty erase
#    ;;
  *)
    stty sane
    ;;
esac

Ο συγκεκριμένος  χρήστης ρυθμίζει  το χαρακτήρα backpspace ανάλογα με το λειτουργικό σύστημα. Εκτός από αυτό, διαβάζονται τα αρχεία .bashrc και .bash_login .


3.1.2.2. ~/.bash_login

Αυτό το αρχείο περιλαμβάνει συγκεκριμένες ρυθμίσεις οι οποίες κανονικά εκτελούνται μόνο όταν κατά τη σύνδεση του χρήστη με στο σύστημα (σε κατάσταση κειμένου).   Στο παράδειγμα, το χρησιμοποιούμε για ν α διαμορφώσουμε την τιμή umask και για να παρουσιάσουμε μία λίστα από συνδεδεμένους χρήστες. Ο χρήστης επίσης λαμβάνει το ημερολόγιο του τρέχοντος μήνα:

 
#######################################################################
#                                                                     #
#   Bash_login file                                                   #
#                                                                     #
#   commands to perform from the bash shell at login time             #
#   (sourced from .bash_profile)                                      #
#                                                                     #
#######################################################################
#   file protection
umask 002       # all to me, read to group and others
#   miscellaneous
w
cal `date +"%m"` `date +"%Y"`

Αν δεν υπάρχει το αρχείο ~/.bash_profile, τότε διαβάζεται απ' ευθείας αυτό το αρχείο.


3.1.2.3. ~/.profile

Στην απουσία των αρχείων ~/.bash_profile και ~/.bash_login, διαβάζεται το αρχείο ~/.profile. Μπορεί να περιέχει τις ίδιες ρυθμίσεις, που τότε είναι προσβάσιμες και σε άλλους φλοιούς. Όμως προσέξτε γιατί άλλοι φλοιοί μπορεί να μην καταλαβαίνουν το συντακτικό του Bash.


3.1.2.4. ~/.bashrc

Σήμερα, όλο και πιο συχνά χρησιμοποιούμε ένα μη-διαλογικό φλοιό, λόγου χάρη όταν συνδεόμαστε σε κατάσταση γραφικής διεπαφής μέσω τερματικού X windows. Καθώς ανοίγουμε  ένα παράθυρο, ο χρήστης δεν χρειάζεται να παρέχει το όνομα χρήστη και τον κωδικό πρόσβασης: άρα δεν πραγματοποείται καμμία ταυτοποίηση. Όταν συμβαίνει αυτό το Bash αναζητά το αρχείο  ~/.bashrc, γι' αυτό και το αρχείο αυτό αναφέρεται σε όλα τα αρχεία διαβάζονται κατά τη σύνδεση, έστι ώστε δεν χρειάζετα να εισάγουμε τις ίδιες ρυθμίσεις σε πολλαπλά αρχεία.

Σε αυτό το αρχείο .bashrc του χρήστη, πρώτα διαβάζουμε το το αρχείο /etc/bashrc για όλο το σύστημα, ενώ στη συνέχεια ορίζουμε μερικά ψευδώνυμα και εκχωρούμε τιμές σε ορισμένες μεταβλητές που χρησιμοποιούνται σε προγράμματα: 

 
franky ~> cat .bashrc
# /home/franky/.bashrc
 
# Source global definitions
if [ -f /etc/bashrc ]; then
       . /etc/bashrc
 
fi
 
# shell options
 
set -o noclobber
 
# my shell variables
 
export PS1="\[\033[1;44m\]\u \w\[\033[0m\] "
export PATH="$PATH:~/bin:~/scripts"
 
# my aliases
 
alias cdrecord='cdrecord -dev 0,0,0 -speed=8'
alias ss='ssh octarine'
alias ll='ls -la'
 
# mozilla fix
 
MOZILLA_FIVE_HOME=/usr/lib/mozilla
LD_LIBRARY_PATH=/usr/lib/mozilla:/usr/lib/mozilla/plugins
MOZ_DIST_BIN=/usr/lib/mozilla
MOZ_PROGRAM=/usr/lib/mozilla/mozilla-bin
export MOZILLA_FIVE_HOME LD_LIBRARY_PATH MOZ_DIST_BIN MOZ_PROGRAM
 
# font fix
alias xt='xterm -bg black -fg white &'
 
# BitchX settings
export IRCNAME="frnk"
 
# THE END
franky ~>

Περισσότερα παραδείγματα μπορούν να βρεθούν στο πακέτο του Bash. Θυμηθείτε οτι μπορεί να απαιτούνται τροποποιήσεις των αρχείων για να δουλέψουν στο περιβλαλλον σας.

Τα ψευδώνυμα συζητώνται στην Ενότητα 3.5.


3.1.2.5. ~/.bash_logout

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

 
franky ~> cat .bash_logout
#######################################################################
#                                                                     #
#   Bash_logout file                                                  #
#                                                                     #
#   commands to perform from the bash shell at logout time            #
#                                                                     #
#######################################################################
clear
franky ~>

3.1.3. Τροποποίηση των αρχείων ρύθμισης φλοιού

Όταν τροποποιούμε οποιοδήποτε από τα παραπάνω αρχεία, οι χρήστες πρέπει είτε να επανασυνδέονται με το σύστημα ή να εκτελούν την εντολή source στα τροποποημένα αρχεία για να ενεργοποιηθούν οι αλλαγές τους. Διερμηνεύοντας με αυτόν τον τρόπο το σενάριο, οι αλλαγές εφαρμόζονται στη τρέχουσα σύνοδο του φλοιού:

Εικόνα 3-1. Διαφορετικές προπτροπές για διαφορετικούς χρήστες

Εικόνα 3-1

Τα περισσότερα σενάρια φλοιού εκτελούνται σε ιδιωτικό περιβάλλον: οι μεταβλητές δεν κληρονομούνται σε θυγατρικές διεργασίες εκτός και αν εξάγονται ρητά (με export) από το γονικό φλοιό. Η εκτέλεση (ή διερμηνεία) ενός αρχείου που περιέχει εντολές φλοιού είναι ένας τρόπος να εφαρμόσουμε αλλαγές στο δικό μας περιβάλλον και να ρυθμίσουμε τις μεταβλητές του τρέχουσας συνόδου φλοιού.

Αυτό το παράδειγμα επίσης επιδεικνύει την χρήση των διαφορετικών ρυθμίσεων προτροπής για διαφορετικές χρήσεις. Σε αυτή τη περίπτωση, κόκκινο σημαίνει κίνδυνος. Όταν έχετε πράσινη προτροπή, τότε να μην ανησυχείτε πολύ.

Παρατηρήστε ότι το source resourcefile είναι το ίδιο με το . resourcefile.

Αν χαθείτε μέσα στα αρχεία ρύθμισης, και βρεθείτε αντιμέτωποι με ρυθμίσεις που η προέλευσή τους δεν είναι ξεκάθαρη, χρησιμοποιείστε προτάσεις echo, ακριβώς όπως στην εκσφαλμάτωση σεναρίων: Δείτε την Ενότητα 2.3.2. Ίσως προσθέσετε γραμμές σαν αυτήν:

 
echo "Now executing .bash_profile.."

ή σαν αυτήν:

 
echo "Now setting PS1 in .bashrc:"
export PS1="[some value]"
echo "PS1 is now set to $PS1"

3.2. Μεταβλητές

3.2.1. Τύποι μεταβλητών

Όπως είδατε στα παραπάνω παραδείγματα, τα ονόματα των μεταβλητών φλοιού γράφονται με κεφαλαίους χαρακτήρες κατά σύμβαση. Ο φλοιός Bash διατηρεί δύο τύπους μεταβλητών:


3.2.1.1. Καθολικές μεταβλητές

Οι καθολικές μεταβλητές ή μεταβλητές περιβάλλοντος είναι διαθέσιμες σε όλους τους φλοιούς. Οι εντολές env ή printenv μπορούν να χρησιμοποιηθούν για την εμφάνιση των μεταβήτών περιβάλλοντος (και των τιμών τους). Αυτά τα προγράμματα βρίσκονται στο πακέτο sh-utils.

Ακολουθεί μια τυπική εμφάνιση:

 
franky ~> printenv
CC=gcc
CDPATH=.:~:/usr/local:/usr:/
CFLAGS=-O2 -fomit-frame-pointer
COLORTERM=gnome-terminal
CXXFLAGS=-O2 -fomit-frame-pointer
DISPLAY=:0
DOMAIN=hq.xalasys.com
e=
TOR=vi
FCEDIT=vi
FIGNORE=.o:~
G_BROKEN_FILENAMES=1
GDK_USE_XFT=1
GDMSESSION=Default
GNOME_DESKTOP_SESSION_ID=Default
GTK_RC_FILES=/etc/gtk/gtkrc:/nethome/franky/.gtkrc-1.2-gnome2
GWMCOLOR=darkgreen
GWMTERM=xterm
HISTFILESIZE=5000
history_control=ignoredups
HISTSIZE=2000
HOME=/nethome/franky
HOSTNAME=octarine.hq.xalasys.com
INPUTRC=/etc/inputrc
IRCNAME=franky
JAVA_HOME=/usr/java/j2sdk1.4.0
LANG=en_US
LDFLAGS=-s
LD_LIBRARY_PATH=/usr/lib/mozilla:/usr/lib/mozilla/plugins
LESSCHARSET=latin1
LESS=-edfMQ
LESSOPEN=|/usr/bin/lesspipe.sh %s
LEX=flex
LOCAL_MACHINE=octarine
LOGNAME=franky
LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:
MACHINES=octarine
MAILCHECK=60
MAIL=/var/mail/franky
MANPATH=/usr/man:/usr/share/man/:/usr/local/man:/usr/X11R6/man
MEAN_MACHINES=octarine
MOZ_DIST_BIN=/usr/lib/mozilla
MOZILLA_FIVE_HOME=/usr/lib/mozilla
MOZ_PROGRAM=/usr/lib/mozilla/mozilla-bin
MTOOLS_FAT_COMPATIBILITY=1
MYMALLOC=0
NNTPPORT=119
NNTPSERVER=news
NPX_PLUGIN_PATH=/plugin/ns4plugin/:/usr/lib/netscape/plugins
OLDPWD=/nethome/franky
OS=Linux
PAGER=less
PATH=/nethome/franky/bin.Linux:/nethome/franky/bin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:/usr/bin:/usr/sbin:/bin:/sbin:.
PS1=\[\033[1;44m\]franky is in \w\[\033[0m\]
PS2=More input>
PWD=/nethome/franky
SESSION_MANAGER=local/octarine.hq.xalasys.com:/tmp/.ICE-unix/22106
SHELL=/bin/bash
SHELL_LOGIN=--login
SHLVL=2
SSH_AGENT_PID=22161
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SSH_AUTH_SOCK=/tmp/ssh-XXmhQ4fC/agent.22106
START_WM=twm
TERM=xterm
TYPE=type
USERNAME=franky
USER=franky
_=/usr/bin/printenv
VISUAL=vi
WINDOWID=20971661
XAPPLRESDIR=/nethome/franky/app-defaults
XAUTHORITY=/nethome/franky/.Xauthority
XENVIRONMENT=/nethome/franky/.Xdefaults
XFILESEARCHPATH=/usr/X11R6/lib/X11/%L/%T/%N%C%S:/usr/X11R6/lib/X11/%l/%T/%N%C%S:/usr/X11R6/lib/X11/%T/%N%C%S:/usr/X11R6/lib/X11/%L/%T/%N%S:/usr/X11R6/lib/X11/%l/%T/%N%S:/usr/X11R6/lib/X11/%T/%N%S
XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB
XMODIFIERS=@im=none
XTERMID=
XWINHOME=/usr/X11R6
X=X11R6
YACC=bison -y

3.2.1.2. Τοπικές μεταβλητές

Οι τοπικές μεταβλητές είναι διαθέσιμες μόνο στο τρέχοντα φλοιό. Με την εσωτερική εντολή set χωρίς άλλες επιλογές εμφανίζουμε όλες τις μεταβλητές (και τις μεταβλητές περιβάλλοντος) καθώς και τις συναρτήσεις. Η έξοδος είναι ταξινομημένη σύμφωνα με την επιλεγμένη γλώσσα και είναι εύκολα επαναχρησιμοποιήσιμη.

Ακολουθεί ένα αρχείο diff (διαφορών) που δημιουργήθηκε συγκρίνοντας τις εξόδους των εντολών printenv και set, μετά την αφαίρεση των συναρτήσεων τις οι οποίες εμφανίζει ηνεντολή set:

 
franky ~> diff set.sorted printenv.sorted | grep "<" | awk '{ print $2 }'
BASE=/nethome/franky/.Shell/hq.xalasys.com/octarine.aliases
BASH=/bin/bash
BASH_VERSINFO=([0]="2"
BASH_VERSION='2.05b.0(1)-release'
COLUMNS=80
DIRSTACK=()
DO_FORTUNE=
EUID=504
GROUPS=()
HERE=/home/franky
HISTFILE=/nethome/franky/.bash_history
HOSTTYPE=i686
IFS=$'
LINES=24
MACHTYPE=i686-pc-linux-gnu
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PIPESTATUS=([0]="0")
PPID=10099
PS4='+
PWD_REAL='pwd
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
THERE=/home/franky
UID=504

 

Note

Awk

Η γλώσσα προγραμματισμού GNU Awk εξηγείται στο Κεφάλαιο 6.


3.2.1.3. Περιεχόμενο μεταβλητών

Εκτός από τη διάκριση των μεταβλητών σε καθολικές και τοπικές, μπορούμε να τις ταξινομήσουμε σε κατηγορίες συμφωνα με το περιεχόμενό τους. Από αυτή την άποψη, οι μεταβλητές χωρίζονται σε 4 τύπους :

         Συμβολοσειρές (αλφαριθμητικά, string)

         Ακέραιοι

         Σταθερές 

         Πίνακες μεταβλητών

Θα συζητήσουμε τους τύπους στο Κεφάλαιο 10. Προς το παρόν, θα εργαστούμε με ακέραιους και συμβολοσειρές.


3.2.2. Δημιουργία μεταβλητών

Τα ονόματα των μεταβλητών είναι ευαίσθητα στη διάκριση μεταξύ πεζών και κεφαλαίων, ενώ οι προεπιλεγμένες μεταβλητές έχουν ονόματα με κεφαλαία γράμαμτα. Συνηθίζεται, χωρίς όμως να είναι υποχρεωτικό, να δίννουμε στις τοπικές μεταβλητές ονόματα με πεζά γράμματα. Τα ονόματα των μεταβλητών μπορούν να περιέχουν ψηφία, αλλά όχι σαν πρώτο χαρακτήρα του ονόματος.

 
prompt> export 1number=1
bash: export: `1number=1': not a valid identifier

Για να ορίσουμε μια μεταβλητή στο φλοιό, γράφουμε:

VARNAME="value"

Αν αφήσουμε κενά πριν ή μετά το ίσον θα προκαλέσουμε σφάλματα. Μια καλή συνήθεια είναι να περικλείουμε τη τιμή της μεταβλητής σε διπλά εισαγωγικά (όπως τις συμβολοσειρές) έτσι ώστε να μην υπάρχει περίπτωση σφάλματος.

Παρακάτω δίνονται μερικά περαδείγματα:

 
franky ~> MYVAR1="2"
 
franky ~7gt; echo $MYVAR1
2
 
franky ~> first_name="Franky"
 
franky ~> echo $first_name
Franky
 
franky ~> full_name="Franky M. Singh"
 
franky ~> echo $full_name
Franky M. Singh
 
franky ~> MYVAR-2="2"
bash: MYVAR-2=2: command not found
 
franky ~> MYVAR1 ="2"
bash: MYVAR1: command not found
 
franky ~> MYVAR1= "2"
bash: 2: command not found
 
franky ~> unset MYVAR1 first_name full_name
 
franky ~> echo $MYVAR1 $first_name $full_name
<--no output-->
 
franky ~>

3.2.3. Εξαγωγή μεταβλητών

Μια μεταβλητή που δημιουργήθηκε όπως παραπάνω είναι διαθέσιμη μόνο στον τρέχοντα φλοιό. Είναι μία τοπική μεταβλητή: οι θυγατρικές διεργασίες του τρέχοντος φλοιού δεν θα γνωρίζουν αυτή τη μεταβλητή. Για να περάσουμε τις μεταβλητές σε ένα υποφλοιό (ή γενικά μια θυγατρική διεργασία), πρέπει να τις εξάγουμε χρησιμοποιώντας την εσωτερική εντολή export. Οι μεταβλητές οι οποίες εξάγονται αναφέρονται ως μεταβλητές περιβάλλοντος. Η δημιουργία και εξαγωγή μπορεί να γίνει σε ένα βήμα:

export VARNAME="value"

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

 
franky ~> full_name="Franky M. Singh"
 
franky ~> bash
 
franky ~> echo $full_name
 
 
franky ~> exit
 
franky ~> export full_name
 
franky ~> bash
 
franky ~> echo $full_name
Franky M. Singh
 
franky ~> export full_name="Charles the Great"
 
franky ~> echo $full_name
Charles the Great
 
franky ~> exit
 
franky ~> echo $full_name
Franky M. Singh
 
franky ~>

Όταν τη πρώτη φορά προσπαθούμε να διαβάσουμε την τιμή της full_name σε ένα υποφλοιό, δεν υπάρχει εκεί (η echo δείχνει μια κενή συμβολοσειρά). Ο υποφλοιός τερματίζεται, και το full_name εξάγεται από τη γονική διεργασία  μια μεταβλητή μπορεί να εξαχθεί μόνο αφού της έχει εκχωρηθεί μια τιμή. Στη συνέχεια ένας νέος υποφλοιός ξεκινάει, στον οποίο η εξαχθείσα μεταβλητή είναι ορατή. Η τιμή της μεταβλητής μεταβάλλεται, και ταυτόχρονα εξάγεται σε μελλοντικές θυγατρικές διεργασίες του υποφλοιού. Όμως, για τη γονική διεργασία η τιμή της μεταβλητής παραμένει η ίδια.


3.2.4. Δεσμευμένες μεταβλητές

3.2.4.1. Δεσμευμένες μεταβλητές του φλοιού Bourne 

Το Bash χρησιμοποιεί ορισμένες μεταβλητές φλοιού με τον ίδιο τρόπο  όπως ο φλοιός Bourne. Σε μερικές περιπτώσεις, το Bash εκχωρεί μια προεπιλεγμένη τιμή σε μία μεταβλητή. Ο πίνακας δίνει μία σύνοψη αυτών των μεταβλητών του απλού φλοιού:

Πίνακας 3-1. Δεσμευμένες μεταβλητές του φλοιού Bourne 

Όνομα μεταβλητής

Ορισμός

CDPATH

Μια λίστα από ονόματα καταλόγων διαχωρισμένων με το σύμβολο :  που χρησιμοποιείται από την εσωτερική εντολή cd

HOME

Ο οικείος κατάλογος του τρέχοντος χρήστη: η προεπιλογή της εντολής cd. Η τιμή αυτής της μεταβλητής επίσης χρησιμοποιεί την επέκταση της  ~

IFS

Λίστα διαχωριστικών χαρακτήρων: χρησιμοποιούνται από τον φλοιό κατά τις επεκτάσεις.

MAIL

Αν η μεταβλητή οριστεί με ένα όνομα αρχείου και η μεταβλητή MAILPATH δεν έχει οριστεί, τότε  το Bash ενημερώνει το χρήστη για την έλευση της αλληλογραφίας στο συγκεκριμένο αρχείο.

MAILPATH

Μια λίστα ονομάτων αρχείων διαχωρισμένων με το σύμβολο : που ελέγχει ο φλοιός περιοδικά για νέα αλληλογραφία.

OPTARG

Η τιμή του τελευταίου ορίσματος επιλογής που επεξεργάστηκε η εσωτερική εντολή getopts.

OPTIND

Ο αριθμοδείκτης του τελευταίου ορίσματος επιλογής που επεξεργάστηκε η εσωτερική εντολή getopts.

PATH

Μια λίστα από ονόματα καταλόγων διαχωρισμένα με το σύμβολο :  που χρησιμοποιείται από το φλοιό για την αναζήτηση εντολών.

PS1

Η βασική προτροπή: η προεπιλεγμένη τιμή είναι "'\s-\v\$ '".

PS2

Η δευτρεύουσα προτροπή: η προεπιλεγμένη τιμή είναι "'> '".


3.2.4.2. Δεσμευμένες μεταβλητές του Bash 

Αυτές οι ματαβλητές ορίζονται από το Bash, οι άλλοι φλοιοί κανονικά δεν τις χειρίζονται με ιδιαίτερο τρόπο.

Table 3-2. Δεσμευμένες μεταβλητές του Bash

Όνομα μεταβλητής

Ορισμός

auto_resume

Αυτή η μεταβλητή ελέγχει πως ο φλοιός διαδρά με τον χρήστη και με τον έλεγχο εργασιών.

BASH

Ολόκληρο το όνομα της διαδρομής που χρησιμοποιείται για την εκτέλεση του τρέχοντος στιγμιοτύπου του Bash.

BASH_ENV

Αν αυτή η μεταβλητή οριστεί, όταν το Bash καλείται να εκτελέσει ένα σενάριο φλοιού, η τιμή της μεταβλητής επεκτείνεται και χρησιμοποιείται ως όνομα ενός αρχείου εκκίνησης που διαβάζεται πριν από την εκτέλεση του σεναρίου.

BASH_VERSION

Ο αριθμός έκδοσης του τρέχοντος στιγμιοτύπου του Bash.

BASH_VERSINFO

Μια μεταβλητή πίνακα μόνο για ανάγνωση της οποίας τα μέλη της διατηρούν πληροφορίες έκδοσης για το τρέχον στιμιότυπο του Bash.

COLUMNS

Χρησιμοποιείται από την εσωτερική εντολή select για να καθορίσει το πλάτος του τερματικού όταν εμφανίζει λίστες επιλογής. Ορίζεται αυτόματα ορίζει με τη λήψη του σήματος SIGWINCH.

COMP_CWORD

Ένας αριθμοδείκτης μέσα στο ${COMP_WORDS} της λέξης που περιέχει την τρέχουσα θέση του δρομέα

COMP_LINE

Η τρέχουσα γραμμή εντολών.

COMP_POINT

Ο αριθμοδείκτης τής τρέχουσας θέσης του δρομέα σε σχέση με την αρχή της τρέχουσας εντολής.

COMP_WORDS

Μια μεταβλητή τύπου πίνακα όπου υπάρχει σε διακεκριμένες λέξεις (tokens) η τρέχουσα γραμμή εντολών.

COMPREPLY

Μια μεταβλητή τύπου πίνακα από την οποία το Bash διαβάζει τις πιθανές συμπληρώσεις που δημιουργούνται από μια συνάρτηση φλοιού που υλοποιεί τη συμπλήρωση γραμμής εντολών (με Tab).

DIRSTACK

Μια μεταβλητή τύπου πίνακα που περιέχει τα τρέχοντα περιεχόμενα της στοίβας καταλόγων.

EUID

Το εκετελστικό ID του τρέχοντος χρήστη.

FCEDIT

Ο συντάκτης κειμένου που χρησιμοποιείται από την επιλογή -e στην εωτερική εντολή fc.

FIGNORE

Λίστα επιθεμάτων χωρισμένων με το σύμβολο :τα οποία αγνοούνται όταν υλοποιείται συμπλήρωση ονομάτων αρχείων.

FUNCNAME

Το όνομα της τρέχουσας εκτελούμενης συνάρτησης του φλοιού.

GLOBIGNORE

Μια λίστα προτύπων  χωρισμένων με το σύμβολο : που ορίζουν τα ονόματα του αρχείου που αγνοούνται κατά την επέκταση ονομάτων αρχέιων.

GROUPS

Μια μεταβλητή τύπου πίνακα που περιέχει την λίστα των ομάδων στις οποίες ο τρέχων χρήστης είναι μέλος.

HISTCHARS

Μέχρι τρεις χαρακτήρες που ελέγχουν τη επέκταση του ιστορικού, γρήγορη υποκατάσταση και το tokenization.

HISTCMD

Ο αριθμός ιστορικού, ή ο αριθμοδείκτης στη λίστα ιστορικού, της τρέχουσας εντολής.

HISTCONTROL

Καθορίζει εάν μία εντολή προστέθηκε στο αρχείο ιστορικού.

HISTFILE

Το όνομα του αρχείου του οποίου το ιστορικό εντολών έχει σωθεί. Η προεπιλεγμένη τιμή είναι ~/.bash_history.

HISTFILESIZE

Ο μέγιστος αριθμός γραμμών που περιέχεται στο αρχείο ιστορικού, προεπιλεγμένος σε  500.

HISTIGNORE

Μια λίστα από πρότυπα χωρισμένα με το συμβολο : που χρησιμοποιούνται για να αποφασισιστεί ποιες γραμμές εντολών πρέπει να αποθηκευθουν στη λίστα ιστορικού.

HISTSIZE

Ο μέγιστος αριθμός από εντολές που ενθυμούνται στη λίστα του ιστορικού, προεπιλεγμένος σε 500.

HOSTFILE

Περιέχει το όνομα αρχείου με την ίδια μορφή όπως το /etc/hosts το οποίο διαβάζεται όταν ο φλοιός χρειάζεται να συμπληρώσει ένα  το όνομα ενός διακομιστή.

HOSTNAME

Το όνομα του τρέχοντος υπολογιστή.

HOSTTYPE

Ένα αλφαριθμητικό που περιγράφει τον τύπο του τρέχοντος υπολογιστή.

IGNOREEOF

Ελέγχει την δράση του φλοιού εάν ληφθεί ένας EOF χαρακτήρας ως μοναδική είσοδος.

INPUTRC

Το όνομα του αρχείου Readline, που υπερβαίνει την προεπιλογή /etc/inputrc.

LANG

Χρησιμοποιείται για να καθορίσει τη γλώσσα (περιοχή) για κάθε περίπτωση που δεν έχει επιλεγεί με τη μεταβλητή που ξεκινά με LC_.

LC_ALL

Αυτή η μεταβλητή αντικαθιστά τη τιμή από τη LANG και απ'ο κάθε άλλη LC_ μεταβλητή.

LC_COLLATE

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

LC_CTYPE

Αυτή η μεταβλητή καθορίζει την ερμηνεία των χαρακτήρων και τη συμπεριφορά των κλάσεων του χαρακτήρα κατά την επέκταση ονόματος του αρχείου και αναγνώριση προτύπων.

LC_MESSAGES

Αυτή η μεταβλητή καθορίζει τη περιοχή (χώρα) που χρησιμοποιείται να μεταφράσει τις συμβολοσειρές σε διπλά εισγωγικά και με σύμβολο"$" μπροστά. .

LC_NUMERIC

Αυτή η μεταβλητή καθορίζει την περιοχή (χώρα) που χρησιμοποιείτε για τον αριθμό μορφοποίησης.

LINENO

Ο αριθμός γραμμής σε ένα σενάριο ή η συνάρτηση φλοιού που εκτελείται επί του παρόντος.

LINES

Χρησιμοποιείτε από την εσωτερική εντολή  select για να καθορίσει το μήκος της στήλης για την εκτύπωση των λιστών επιλογής.

MACHTYPE

Μια συμβολοσειρά που περιγράφει πλήρως το τύπο του συστήματος στο οποίο εκτελείται το Bash, στη  επίσημη GNU CPU-COMPANY-SYSTEM μορφή.

MAILCHECK

Πόσο συχνά (σε δευτερόλεπτα) όπου ο φλοιός θα πρέπει να ελέγχει για αλληλογραφία στα αρχεία που καθορίζονται μέσα στις μεταβλητές MAILPATH ή MAIL.

OLDPWD

Ο προηγούμενος τρέχων κατάλογος που ορίζεται από τηνεσωτερική εντολή cd.

OPTERR

Αν οριστεί η τιμή 1, το  Bash προβάλει μηνύματα λάθους που παράγει η εσωτερική εντολή getopts.

OSTYPE

Ένα αλφαριθμητικό που περιγράφει το λειτουργικό σύστημα που εκτελείται το Bash .

PIPESTATUS

μία μεταβλητή τύπου πίνακα που περιέχει μία λίστα από τιμές κατάστασης εξόδου των διεργασιών  από τη πιο πρόσφατα εκτελεσμένη σωλήνωση προσκηνίου. (οι οποίες ίσως να περιέχουν μόνο μια μοναδική εντολή).

POSIXLY_CORRECT

Αν αυτή η μεταβλητή είναι στο περιβάλλον όταν ξεκινά το bash, τότε ο φλοιός εσέρχεται σε κατάσταση POSIX.

PPID

Το ID της της γονικής διεργασίας του τρέχοντος φλοιού .

PROMPT_COMMAND

Αν οριστεί, τότε η τιμή ερμηνεύεται ως μία εντολή προς εκτέλεση πριν από την εκτύπωση της κάθε βασικής προτροπής (PS1).

PS3

Η τιμή αυτής της μεταβλητής χρησιμοποιείται ως προτροπή για την  εντολή select. Προεπιλογή ως "'#? '"

PS4

Η τιμή είναι μία προτροπή που εμφανίζεται στη γραμμή εντολών όταν έχει οριστεί η επιλογή -x: Προεπιλογή ως "'+ '".

PWD

Ο  τρέχων κατάλογος εργασίας που ορίζεται από την εσωτερική εντολή cd.

RANDOM

Κάθε φορά που αναφέρεται αυτή η μεταβλητή, δημιουργείται μία τυχαία μεταβλητή μεταξύ του 0 και 32767. Η τιμή που τίθεται αρχικά στην μεταβλητή χρησιμοποιείται  ως seed..

REPLY

Η προεπιλεγμένη μεταβλητή για την εσωτερική εντολή read.

SECONDS

Αυτή η μεταβλητή κρατά τον αριθμό των δευτερολέπτων από τότε που ξεκίνησε ο φλοιός.

SHELLOPTS

Μια λίστα των ενεργοποιημένων επιλογών του φλοιού, χωρισμένων με :.

SHLVL

Αυξάνεται κατά ένα κάθε φορά που ένα νέο στιγμιότυπο του Bash ξεκινά.

TIMEFORMAT

Η τιμή αυτής της παραμέτρου χρησιμοποιείται ως ένα αλφαριθμητικό μορφοποίησης των πληροφοριών χρονιμού για σωληνώσεις με το πρόθεμα time.

TMOUT

Αν οριστεί μία τιμή μεγαλύτερη από ότι το μηδέν, η TMOUT συμπεριφέρεται όπως η προεπιλεγμένη timeout για την εσωτερική εντολή read. Σε ένα διαλογικό φλοιό, η τιμή ερμηνεύεται ως ο αριθμός από δευτερόλεπτα που περιμένει για εισαγωγή μετά από την εμφάνιση της βασικής προτροπής. Αν, μετά από ένα αριθμό δευτερολέπτων δεν υπάρχει είσοδος το Bash τερματίζει.

UID

Το πραγματικό ID του τρέχοντος χρήστη.

Ελέγξτε το man του Bash, για πληροφορίες ή σελίδες doc για εκτεταμένες πληροφορίες. Μερικές μεταβλητές είναι μόνο για ανάγνωση, μερικές ορίζονται αυτόματα και μερικές χάνουν την σημασία τους θέτοντας τιμή διαφορετική από την προεπιλεγμένη.


3.2.5. Ειδικές παράμετροι

Ο φλοιός μεταχειρίζεται ορισμένες μεταβλητές με ειδικό τρόπο. Αυτές οι μεταβλητές (ή παράμετροι) μπορούν μόνο να διαβαστούν,  δεν επιτρέπεται η ανάθεση τιμών σε αυτές.

Πίνακας 3-3. Ειδικές μεταβλητές του Βash

Χαρακτήρας

Ορισμός

$*

Επεκτείνει μία παράμετρο θέσης, ξεκινώντας από το ένα. Όταν η επέκταση βρίσκεται μέσα σε διπλά εισαγωγικά, επεκτείνεται σε ξεχωριστές παραμέτρους με βάση τον πρώτο χαρακτήρα από την ειδική μεταβλητή IFS.

$@

Επεκτείνει μία παράμετρο θέσης, ξεκινώντας από το ένα. Όταν η επέκταση βρίσκεται μέσα σε διπλά εισαγωγικά, κάθε λέξη επεκτείνεται σε ξεχωριστή παράμέτρο.

$#

Επεκτείνει τον αριθμό των παραμέτρων θέσης σε δεκαδική μορφή.

$?

Επεκτείνει την κατάσταση εξόδου της πιο πρόσφατα εκταλεσμένης σωλήνωσης..

$-

Επεκτείνεται στις τρέχουσες επιλογές είτε όπως ορίστηκαν στην κλήση, ειίτε από την εσωτερική εντολή set,ή από τον ίδιο το φλοιό (όπως το -i).

$$

Επεκτείνεται στο ID διαργασίας του φλοιού..

$!

Επεκτείνεται στοs ID γασίας της πιο πρόσφατα εκετελεσμένης εντολής παρασκηνίου.

$0

Επεκτείνεται στο όνομα του φλοιού ή του σεναρίου που εκτελείται.

$_

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

Οι παράμετροι θέσης είναι οι λέξεις που ακολουθούν το όνομα του σεναρίου φλοιού. Αυτές τοποθετούνται στις μεταβλητές $1, $2, $3  κλπ.  Εφόσον χρειαστεί, οι μεταβλητές τοποθετούνται σε έναν εσωτερικό πίνακα. Η παράμτερος $# διατηρεί το συνολικό αριθμό των παραμέτρων, όπως φαίνεται στο παρακάτω απλό σενάριο:

 
#!/bin/bash
 
# positional.sh
# This script reads 3 positional parameters and prints them out.
 
POSPAR1="$1"
POSPAR2="$2"
POSPAR3="$3"
 
echo "$1 is the first positional parameter, \$1."
echo "$2 is the second positional parameter, \$2."
echo "$3 is the third positional parameter, \$3."
echo
echo "The total number of positional parameters is $#."

Στην εκτέλεση μπορείτε να δώσετε οποιοδήποτε αριθμό ορισμάτων:

 
franky ~> positional.sh one two three four five
one is the first positional parameter, $1.
two is the second positional parameter, $2.
three is the third positional parameter, $3.
 
The total number of positional parameters is 5.
 
franky ~> positional.sh one two
one is the first positional parameter, $1.
two is the second positional parameter, $2.
 is the third positional parameter, $3.
 
The total number of positional parameters is 2.

Περισσότερα για τη χρήση αυτών των παραμέτρων στο Κεφάλαιο 7 και στην Ενότητα 9.7.

Μερικά παραδείγματα των άλλων ειδικών παραμέτρων:

 
franky ~> grep dictionary /usr/share/dict/words
dictionary
 
franky ~> echo $_
/usr/share/dict/words
 
franky ~> echo $$
10662
 
franky ~> mozilla &
[1] 11064
 
franky ~> echo $!
11064
 
franky ~> echo $0
bash
 
franky ~> echo $?
0
 
franky ~> ls doesnotexist
ls: doesnotexist: No such file or directory
 
franky ~> echo $?
1
 
franky ~>

Ο χρήστης franky ξεκινά με την εντολή grep, που έχει ως αποτέλεσμα τον ορισμό της μεταβλητής _ . Το ID διεργασίας αυτού του φλοιού είναι 10662. Αφού τοποθετήσουμε μια δουλειά στο παρασκήνιο, η μεταβλητή ! κρατά το ID της διεργασίας παρασκηνίου. Η διεργασία που εκτελέιται είναι το bash. Όταν γίνει κάποιο σφάλμα η μεταβλητή ? έχει τιμή διάφορη του μηδενός.


3.2.6. Ανακύκλωση σεναρίων με μεταβλητές

Εκτός από το να κάνουμε το σενάριο πιο ευανάγνωστο, οι ματαβλητές μας επιτρέπευν να εφαρμόσυμε το ίδιο σενάριο σε διαφορετικά περιβάλλοντα ή για άλλο σκοπό. Θεωρείστε το ακόλουθο παράδειγμα, ένα πολύ απλό σενάριο που δημιουργεί ένα εφεδρικό αντίγραφο του οικείου καταλόγου του franky σε ένα απομακρυσμένο διακομιστή:

 
#!/bin/bash
 
# This script makes a backup of my home directory.
 
cd /home
 
# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1
 
# First remove the old bzip2 file.  Redirect errors because this generates some if the archive
# does not exist.  Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar
 
# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1
 
# Create a timestamp in a logfile.
date > /home/franky/log/home_backup.log
echo backup succeeded > /home/franky/log/home_backup.log

Πρώτα από όλα, είναι πολύ πιθανό να κάνετε λάθη αν ονομάζετε τα αρχεία και τους καταλόγους με το χέρι κάθε φορά που τα χρειάζεστε. Δεύτερο, υποθέστε ότι ο franky θέλει να δώσει αυτό το σενάριο στη carol, τότε η  carol θα πρέπει να κάνει σχεδόν τις ίδιες διορθώσεις πριν χρησιμοποιήσει το σενάριο για να αντιγράψει το προσωπικό της κατάλογο. Το ίδιο συμβαίνει αν ο franky θέλει να χρησιμοποιήσει το σενάριο για την αντιγραφή άλλων καταλόγων. Για εύκολη ανακύκλωση, κάντε όλα τα αρχεία, καταλόγους, όνομα χρηστη, ονόμα διακομιστή, κλπ μεταβλητές. Έτσι, χρειάζεστε να τροποποιήσετε το σενάριο σε ένα μόνο τμήμα του, χωρίς να πρέπει να ελέγξετε ολόκληρο του σενάριο κάθε φορά. Να ένα παράδειγμα:

 
#!/bin/bash
                                                                                                 
# This script makes a backup of my home directory.
 
# Change the values of the variables to make the script work for you:
BACKUPDIR=/home
BACKUPFILES=franky
TARFILE=/var/tmp/home_franky.tar
BZIPFILE=/var/tmp/home_franky.tar.bz2
SERVER=bordeaux
REMOTEDIR=/opt/backup/franky
LOGFILE=/home/franky/log/home_backup.log
 
cd $BACKUPDIR
 
# This creates the archive
tar cf $TARFILE $BACKUPFILES > /dev/null 2>&1
                                                                                                 
# First remove the old bzip2 file.  Redirect errors because this generates some if the archive 
# does not exist.  Then create a new compressed file.
rm $BZIPFILE 2> /dev/null
bzip2 $TARFILE
 
# Copy the file to another host - we have ssh keys for making this work without intervention.
scp $BZIPFILE $SERVER:$REMOTEDIR > /dev/null 2>&1
 
# Create a timestamp in a logfile.
date > $LOGFILE
echo backup succeeded > $LOGFILE

 

Note

Μεγάλοι κατάλογοι και μικρό εύρος ζώνης

Το παραπάνω είναι απλώς ένα παράδειγμα που ο καθένας μπορεί να το καταλάβει, χρησιμοποιεί ένα μικρό κατάλογο και ένα διακομιστή στο ίδιο το υποδίκτυο.Ανάλογα με το εύρος ζώνης σας, το μέγεθος του καταλόγου και την τοποθεσία του απομακρυσμένου διακομιστή, η αντιγραφή με αυτό το μηχανισμό μπορεί να πάρει υπερβολικά πολλή ώρα. Για μεγαλύτερους καταλόγους και χαμηλότερο εύρος ζώνης, χρησιμοποιήστε το rsync για να διατηρήσετε τους δύο καταλόγους συγχρονισμένους.


3.3. Χαρακτήρες σε εισαγωγικά

3.3.1. Γιατί;

Mερικοί χαρακτήρες έχουν διαφορετικό νόημα σε διαφορετικά συμφραζόμενα. Τα εισαγωγικά χρησιμοποιούνται για να αφαιρέσουν την ειδική σημασία από χαρακτήρες ή λέξεις: τα εισαγωγικά ακυρώνουν τους ειδικούς χειρισμούς σε χαρακτήρες, αποτρέπουν την αναγνώριση δεσμευμένων λέξεων και ακυρώνουν την επέκταση παραμέτρων.


3.3.2. Χαρακτήρες διαφυγής

Οι χαρακτήρες διαφυγής χρησιμοποιούνται για την αφαίρεση ειδικής σημασίας από μεμονωμένους χαρακτήρες. Στο Bash ο χαρακτήρας διαφυγής είναι το backslash \. Διατηρεί την κυριολεκτική τιμή του χαρακτήρα, με εξαίρεση την αλλαγή γραμμής (newline). Αν αμέσως μετά το backslash εμφανίζεται χαρακτήρας αλλαγής γραμμής, τότε αυτό σημαίνει συνέχεια της ίδιας εντολής σε νέα γραμμή. Το backslash αφαιρείται μαζί με την αλλαγή γραμμής δεν λαμβάνεται υπ' όψη στην είσοδο.

 
franky ~> date=20021226
 
franky ~> echo $date
20021226
 
franky ~> echo \$date
$date

Σε αυτό το παράδειγμα, η μεταβλητή date δημιουργήθηκε και πήρε μια τιμή. Η πρώτη εντολή echo εμφανίζει τη τιιμή της μεταβλητής, αλλά στη δέυτερη η σημασία του $ (περιεχόμενο) ακυρώνεται.


3.3.3. Απλά εισαγωγικά

Τα απλά εισαγωγικά ('') χρησιμοποιούνται για την ακύρωση ειδικής σημασίας ομάδας χαρακτήρων που βρίσκονται μεταξύ των εισαγωγικών (σαν ο κάθε χαρακτήρας να είχε μπροστά του backslash). Ένα απλό εισαγωγικό δεν μπορεί να βρεθεί μεταξύ δύο απλών εισαγωγικών, ακόμη και αν προηγείται backslash.

Συνεχίζουμε στο ίδιο παράδειγμα:

 
franky ~> echo '$date'
$date

3.3.4. Διπλά εισαγωγικά

Με τα διπλά εισαγωγικά οι χαρακτήρες διατηρούν την κυριoλεκτική τιμή τους, εκτός από το δολλάριο, τα ανάποδα εισαγωγικά (βαρείες, backticks ``) και το backslash.

Το δολλάριο και οι βαρείες διατηρούν την ειδική σημασία τους.

Το backslash διατηρεί τη σημασία του μόνο αν ακολουθείται από δολλάριο, βαρεία, διπλό εισαγωγικό, backslash ή αλλαγή γραμμής. Σε αυτές τις περιπτώσεις το backslash απλά αφαιρείται από τη συμβολοσειρά είσοδου. Στις υπόλοιπες περιπτώσεις το backslash δεν τροποποείται και υφίσταται κανονική επεξεργασία από τον διερμηνέα του φλοιού.

Ένα διπλό εισαγωγικό μπορεί να βρίσκεται μεταξύ διπλών εισαγωγικών αρκεί να προηγείται backslash.

 
franky ~> echo "$date"
20021226
 
franky ~> echo "`date`"
Sun Apr 20 11:22:06 CEST 2003
 
franky ~> echo "I'd say: \"Go for it!\""
I'd say: "Go for it!"
 
franky ~> echo "\"
More input>"
 
franky ~> echo "\\"
\

3.3.5. ANSI-C εισαγωγικά

Λέξεις με τη μορφή "$'STRING'"υφίστανται ειδική μεταχείριση. Η λέξη επεκτείνεται σε συμβολοσειρά με τους χαρακτήρες που ακολουθούν backslash να αντικαθίστανται με βάση το πρότυπο της ANSI-C standard. Τα πρότυπα μπορούν να βρεθούν στη τεκμηρίωση του Bash.


3.3.6. Τοπικές γλωσσικές συμβάσεις (locales)

Ένα αλφαριθμητικό σε διπλά ειαγωγικά που ακολουθεί είναι δολλάριο θα μεταφραστεί με βάση τις τρέχουσες τοπικές γλωσσικές συμβάσεις (locales). Αν η τοπική γλψσσική σύμβαση σύμβαση είναι "C" ή "POSIX",το δολλάριο αγνοείται  Αν η συμβολοσειρά μετφραστεί και αντικατασταθεί, η νέα συμβολοσειρά μπαίνει σε διπλά εισαγωγικά.


3.4. Επέκταση φλοιού

3.4.1. Γενικά

Αφού η γραμμή εντολών διασπαστεί σε σύμβολα (tokens) (δείτε Ενότητα 1.4.1.1), τα σύμβολα αυτά επεκτείνονται και αντικαθίστανται. Υπάρχουν οκτώ τύποι επέκτασης, που θα συζητηθούν στις επόμενες ανότητες, με τη σειρά που γίνονται οι επεκτάσεις. 

Μετά από όλες τις επεκτάσεις, αφαιρούνται τα εισαγωγικά.


3.4.2. Επέκταση αγκυλών

Η επέκταση αγκυλών είναι ένας τρόπος δημιουργίας αυθαίρετων συμβολοσειρών. Τα προς επέκταση πρότυπα έχουν τη παρακάτω μορφή: ένα προαιρετικό ΠΡΟΘΕΜΑ (PREAMBLE), μια ακολουθία από συμβολοσειρές, χωρισμένες με κόμμα, που περικλείονται με ένα ζεύγος αγκυλών,  και ένα προαιρετικό ΕΠΙΘΕΜΑ (POSTSCRIPT). Το πρόθεμα προστίθεται στην αρχή κάθε συμβολοσειράς που βρίσκεται μέσα στις αγκύλες, ενώ το επίθεμα προστίθεται στο τέλος. Επέκταση γίνεται από αριστερά προς δεξιά. 

Οι επεκτάσεις αγκυλών μπορεί να είναι ένθετες. Τα αποτελέσματα των επεκτάσεων δεν ταξινομούνται, και διατηρείται η σειρά αριστερά προς δεξιά.

 
franky ~> echo sp{el,il,al}l
spell spill spall

Η επέκταση αγκυλών υλοποιείται πριν από κάθε άλλη επέκταση, και πιθανοί ειδικοί χαρακτήρες διατηρούνται στο αποτέλεσμα. Η επέκταση είναι καθαρά αλφαριθμητική: το Bash δεν αφαρμόζει καμμία συνατκτική ή άλλη διερμηνεία στα συμφραζόμενα της επέκτασης. Για να αποφευχθούν συγκρούσεις με την επέκταση παραμέτρων, η συμβολοσειρά  "${" δεν θεωρείται νόμιμη στην επέκταση αγκυλών.

Μια σωστά διατυπωμένη επέκταση αγκυλών πρέπει να περιέχει δύο εξωτερικές αγκύλες (άνοιγμα και κλείσιμο) χωρίς εισαγωγικά, και τουλάχιστο ένα κόμμα χωρίς εισαγωγικά. Αν δεν είναι σωστά διατυπωμένη η επέκταση αγκυλών παραμένει ως έχει.


3.4.3. Επέκταση περισπωμένης  (tilde)

Αν μια λέξη (σύμβολο) ξεκινά με ένα περισπωμένη (tilde character ~) χωρίς εισαγωγικά, όλοι οι χαρακτήρες μέχρι τη πρώτη κάθετο (slash) εκτός εισαγωγικών (ή όλοι οι χαρακτήρες, αν δεν υπάρχει τέτοια κάθετος) θεωρούνται ως πρόθεμα περισπωμενης (tilde-prefix). Αν κανείς από τους χαρατήκτρες αυτούς δεν είναι σε εισαγωγικά, οι χαρακτήρες του προθέματος αντιμετωπίζονται ως πιθανό όνομα σύνδεσης. Αν το όνομα σύνδεσης είναι κενό αλφαριθμητικό, η περισπωμένη αντικαθίσταται από την τιμή της μεταβλητής φλοιού HOME. Αν η μεταβλητή HOME δεν έχει οριστεί, τότε χρησιμοποιείται ως τιμή αντικατάστασης το όνομα διαδρομής του οικείου καταλόγου του χρήστη που εκτελεί το φλοιό. Αν το όνομα σύνδεσης δεν είναι κενό αλφαριθμητικό τότε η τιμή αντικατάστασης είναι ο οικείος κατάλογος που σχετίζεται με το συγκεκριμένο όνομα σύνδεσης.

Αν το πρόθεμα περισπωμένης είναι "~+", αντικαθίσταται από την τιμή της μεταβλητής φλοιού PWD. Αν το πρόθεμα περισπωμένης είναι "~-", αντικαθίσταται από την τιμή της μεταβλητής φλοιού OLDPWD.

Αν οι χαρακτήρες στο πρόθεμα μετά τη περισπωμένη είναι ένας αριθμός N, προαιρετικά με  "+" ή "-" μπροστά του, το πρόθεμα αντικαθίσταται με το αντίστοιχο στοιχείο από τη στοίβα των καταλόγων, όπως θα εμφανιζόταν αν καλούσαμε την εσωτερική εντολή dirs με τους χαρακτήρες μετά τη περισπωμένη ως όρισμα. Αν δεν υπάρχει "+" ή "-", εννοείεται το "+".

Αν το όνομα σύνδεσης είναι άκυρο ή η επέκταση της περισπωμένης αποτύχει, το σύμβολο παραμένει αμετάβλητο.

Κάθε εκχώρηση μεταβλητής ελέγχεται για προθέματα περισπωμένης χωρίς εισαγωγικά, που ακολουθούν αμέσως μετά από ":" ή "=". Σε αυτές τις περιπτώσεις, επίσης εφαρμόζεται επέκταση περισπωμένης. Συνακόλουθα, μπορούμε να χρησιμοποιήσουμε ονόματα αρχείων με περισπωμένη στους ορισμούς των PATH, MAILPATH, και CDPATH, και ο φλοιός εκχωρεί την εκεταμένη τιμή.

Παράδειγμα:

 
franky ~> export PATH="$PATH:~/testdir"

Το ~/testdir θα επεκταθεί σε $HOME/testdir, έτσι αν το $HOME είναι /var/home/franky, ο κατάλογος /var/home/franky/testdir θα προστεθεί στη τιμή της μεταβλητής PATH.


3.4.4. Επέκταση παραμέτρων και μεταβλητών φλοιού

Ο χαρακτήρας "$" εισάγει επέκταση παραμέτρων, αντικατάσταση εντολών ή αριθμητική επέκταση. Το όνομα της παραμέτρου ή το σύμβολο προς επέκταση μπορεί να περικλείεται σε αγκύλες, που είναι προαιρετικές αλλά προστατεύουν την προς επέκταση μεταβλητή από χαρακτήρες που ακολουθούν αμέσως μετλα και θα μπορούσαν να θεωρηθούν ως τμήμα του ονόματος.

Όταν χρησιμοποιούνται αγκύλες, η αγκύλη κλεισίματος είναι πρώτη  αγκύλη "}" που δεν αναιρείται με backslash, δε βρίσκεται μέσα σε εισαγωγικά, ή σε αριθμητική έκφραση, αντικατάσταση εντολής ή επέκταση παραμέτρων. 

Η βασική μορφή επέκτασης παραμέτρων είναι "${PARAMETER}". Η τιμή του "PARAMETER" αντικαθίσταται. Οι αγκύλες απαιτούνται όταν το "PARAMETER" είναι παράμετρος θέσης με περισσότερα από ένα ψηφία, ή όταν το "PARAMETER" ακολουθείται από ένα χαρακτήρα που δεν πρέπει να ληφθεί ως μέρος του ονόματος. 

Αν ο πρώτος χαρακτήρας στο "PARAMETER" είναι θαυμαστικό, το Bash χρησιμοποιεί την τιμή που αντιστοιχεί στην μεταβλητή με το όνομα που σχηματίζουν οι υπόλοιποι χαρακτήρες του "PARAMETER" Αυτό λέγεται έμμεση επέκταση (indirect expansion).

Σίγουρα γνωρίζετε την απλή επέκταση παραμέτρων (και μεταβλητών) φλοιού αφού συμβαίνει συνέχεθα, ακόμη και στις απλούστερες περιπτώσεις, όπως η ακόλουθη:

 
franky ~> echo $SHELL
/bin/bash

Το παρακάτω είναι παράδειγμα έμμεσης επέκτασης:

 
franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH

Σημειώστε οτι είναι διαφορετικό από το echo $N*.

Η ακόλουθη δομή επιτρέπει τη δημιουργία μεταβλητής ορισμό τιμής:

${VAR:=value}

Παράδειγμα:

 
franky ~> echo $FRANKY
 
franky ~> echo ${FRANKY:=Franky}
Franky

Οι ειδικές παράμετροι, όπως οι  παράμετροι θέσης, δεν μπορούν να οριστούν με αυτό το τρόπο, προφανώς.

Θα συζητήσουμε περισσότερο τη χρήση αγκυλών στην διαχείριση μεταβλητών στο Κεφάλαιο 10. Περισσότερες πληροφορίες στις σελίδες πληροφοριών του Bash.


3.4.5. Αντικατάσταση εντολών

H aντικατάσταση εντολών επιτρέπει την έξοδο μιας εντολής να αντκαταστήσει την ίδια την εντολή. Αυτό συμβαίνει όταν μια εντολή γράφεται ως εξής :

$(command)

ή περικελιεται με βαρείες:

`command`

Το Bash εκτελεί την επέκταση με την εκτέλεση της εντολής και με αντικατάσταση της με την τυπική έξοδό της, αφαιρώντας πιθανές κενές γραμμές. Σε περίπτωση που υπάρχουν ενδιάμεσες σλλαγές γραμμήςς στη έξοδο αφαιρούνται επίσης.

 
franky ~> echo `date`
Thu Feb 6 10:06:20 CET 2003

Όταν χρησιμοποιείται η σύνταξη με τις βαρείες, το backslash διατηρεί την κυριολεκτική του σημασία εκτός αν ακολουθείται από "$", "`", ή "\". Η πρώτη βαρεία που δεν ακολουθεί backslash τερματίζει την αντικατάσταση εντολήε. Όταν χρησιμοποιείται τη μορφή "$(COMMAND)" όλοι οι χαρακτήρες μεταξύ των παρενθέσεων θεωρούνται ως εντολή, χωρίς κανένας χαρακτήρας να έχει ειδική σημασία.

Η αντικατάσταση εντολών μπορεί να είναι ένθετη. Αν η αντικατάσταση βρίσκεται μέσα σε διπλά εισαγωγικά, το αποτέλεσμα δεν υφίσταται τεμαχισμό σε λέξεις και επεκταση ονομάτων.


3.4.6. Αριθμητική επέκταση

Η αριθμητική επέκταση επιτρέπει την εκτίμηση αριθμητικών εκφράσεων και αντικατάσταση του αποτελέσματος. H μορφή της αριθμητικής επέκτασης είναι:

$(( EXPRESSION ))

Η έκφαση αντιμετωπίζεται σαν να είναι μέσα σε διπλά εισγωγικά, αλλά ένα διπλό εισαγωγικό μέσα στην έκφραση δεν αντιμετωπίζεται ιδιαίτερα. Όλα τα σύμβολα της έκφρασης υφίsτανται επέκταση παραμέτρων, αντικατάσταση εντολών και αφαίρεση εισαγωγικών. Η αριθμητική αντικατάσταση μπορεί να είναι ένθετη.

Η εκτίμηση των αριθμητικών εκφράσεων γίνεται με ακεραίους σταθερού πλάτους, χωρίς έλεγχο υπερχείλισης -αν και η διαίρεση με το μηδέν παγιδεύεται  και αναγνωρίζεται ως σφάλμα, Οι τελεστές είναι περίπου οι ίδιοι με την γλώσσα προγραμματισμού C. Σε διάταξη μειούμενης προτεραιότητας, η λίστα έχει ως εξής:

Πίνακας 3-4. Αριθμητικοί τελεστές

Τελεστής  

Σημασία

VAR++ και VAR--

μετα-αύξηση και μετα-μείωση μεταβλητής

++VAR και --VAR

προ-αύξηση και προ-μείωση μεταβλητής

- και +

μοναδιαίο μείον και συν

! και ~

λογική και bitwise άρνηση

**

ύψωση σε δύναμη

*, / και %

πολ/σμός, διαίρεση, ακέραιο υπόλοιπο

+ και -

πρόσθεση, αφαίρεση

<< και >>

αριστερή και δεξιά ολίσθηση

<=, >=, < και >

τελεστές σύγκρισης

== και !=

ισότητα και ανισότητα

&

bitwise AND

^

bitwise ΧOR

|

bitwise OR

&&

λογικό AND

||

λογικό OR

expr ? expr : expr

εκτίμηση υπό συνθήκη

=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^= and |=

εκχωρήσεις

,

διαχωριστικό μεταξύ εκφράσεων

Οι μεταβλητές φλοιού επιτρέπεται να είναι τελεστές. Η επέκταση παραμέτρων γίνεται πριν την εκτίμηση της έκφρασης. Μέσα σε μια έκφραση οι τιμές των μεταβλητών μπορούν να προσπελαστούν χωρίς την χρήση της σύνατξης επέκτασης παραμέτρων. Οι μεταβλητές φλοιού δεν είναι απαραίτητο να είναι δηλωμένες ως ακέραιοι.

Σταθερές που ξεκινούν με 0 (μηδέν) ερμηνεύονται ως οκταδικοί αριθμοί. Αν ξεκινούν με "0x" ή "0X" τότε θεωρούνται δεκαεξαδικοί. Αλλιώς οι αριθμοί παίρνουν τη μορφή  "[BASE'#']N", όπου "BASE" είναι δεκαδικός αριθμός μεταξύ 2 και 64 και παριστά την αριθμητκή βάση, και N είναι ο αριθμός σε αυτή τη βάση. Αν το τμήμα "BASE'#'" παραλείπεται, τότε ως βάση εννοε;iται το 10. Ψηφία μεγαλύτερα του 9 παριστώνται  με πεζά, κεφαλαία γράμματα  και τα σύμβολα, "@", και "_", με τη σειρά που αναφέρονtαι. Αν η βάση είναι μικρότερη ή ίση με 36, τα πεζά και κεφαλαία μπορούν να αναμιχθούν για τη παράσταση αριθμών από το 10 ως το 35.

Οι τελεστές εκτιμώνται με σειρά προτεραιότητας, υπο-εκφράσεις σε παρενθέσεις εκτιμώνται πρώτες και υπερβαίνουν τους κανόνες προτεραιότηατς.

Όταν είναι δυνατό οι χρήστες του Bash καλό είναι να χρησιμοποιούν τη σύνταξη με τις ορθογώνιες παρενθέσεις:

$[ EXPRESSION ]

Όμως αυτό απλά υπολογίζει την έκφραση EXPRESSION, και δεν κάνει ελέγχους:

 
franky ~> echo $[365*24]
8760

Δείτε την Ενότητα 7.1.2.2, μεταξύ άλλων, για πρακτικά παραδείγματα με σενάρια.


3.4.7. Αντικατάσταση διεργασιών

Η αντικατάσταση διεργασιών χρησιμοποιείται σε συστήματα που υποστηρίζουν ονομασμένες σωληνώσιες (FIFOs) ή τη μέθοδο  /dev/fd για την ονομασία ανοικτών αρχείων. Έχει τη μορφή

<(LIST)

ή

>(LIST)

Η λίστα των διεργασιών εκτελείται με την είσοδο ή έξοδο συνδεδεμένη σε μια σωλήνωση FIFO ή σε κάποιο αρχείο στο /dev/fd. Το όνομα αυτού του αρχείου περνάει ως όρισμα στη τρέχουσα εντολή ως αποτέλεσμα της επέκτασης. Αν χρησιμοποιηθεί η μορφή ">(LIST)" τότε το αρχείο αποτελεί είσοδο για τη λίστα , αλλιώς αποτελεί την έξοδο. Σημιώστα οτι δεν επιτρέπονται κενά μεταξύ των συμβόλων < και > και της αριστερής παένθεσης, αλλιώς η δομή ερμηνεύεται ως ανακατεύθυνση.

Όταν διατίθεται, η αντικατάσταση διεργασιών γίνεται ατυτόχρονα με τις άλλες επεκτάσεις και αντικαταστάσεις.

Περισσότερες πληροφορίες στην Ενότητα 8.2.3.


3.4.8. Χωρισμός λέξεων

Ο φλοιός σαρώνει το αποτέλεσμα των επεκτάσων και αντικαταστάσεων που δεν βρίσκονται μέσα σε διπλά εισαγωγικά για χωρισμό λέξεων.

Κάθε χαρακτήρας στο $IFS θεωρείται ως οριοθέτης, και ο φλοιός χωρίζει το εποτέλεσμα σε λέξεις με βάση αυτούς τους οριοθέτες. Αν η μεταβλητή IFS δεν είναι ορισμένη, ή η τιμή της είναι το προκαθορισμένο "'<space><tab><newline>'", τότε οποιαδήποτε ακολουθία από αυτούς τους χαρακτήρες θεωρείατι οτι οριοθετεί μια λέξη. Αν η μεταβλητή IFS έχει τιμή null τότε δεν γίνεται κανένας χωρισμόας. Αν η μεταβλητή IFS έχει άλλη τιμή τότε η οριοθέτηση γίνεται με συνδυασμό των χαρακτήρων οριοθέτησης και των συνηθισμένων 'λευκών' χαρακτήρων.

Ορίσματα που είναι ρητά κενά  ("""" or "''") διατηρούνται. Κενά ορίσματα χωρίς εισαγωγικά που προκύπτουν από την επεέκταση παραμέτρων χωρίς τιμή, παραλείπονται.

Note

Επεκτάσεις και χωρισμός λέξεων

Αν δεν γίνουν επεκτάσεις τότε δεν γίνεται και χωρισμός λέξεων.


3.4.9. Επέκταση ονομάτων αρχείων

Μετά το χωρισμό λέξεων, και αν δεν έχει τεθεί η επιλογή -f (δείτε Ενότητα 2.3.2), το Bash σαρώνει κάθε λέξη για χαρακτήρες "*", "?", και "[". Αν βρεθεί τέτοιος χαρακτήρας, η λέξη θεωρείται ΠΡΟΤΥΠΟ (PATTERN), και αντικαθίσταται με αλφαβητικά ταξινομημένη λίστα ονομάτων αρχείων που ταιριάζουν. Αν δεν υπάρχουν ονόματα αρχείων που ταυτίζονται, και η επιλογή φλοιού nullglob είναι απενεργοποιημένη, η λέξη μένει αμετάβλητη. Αν η επιλογή nullglob είναι ορισμένη, και δεν υπάρχουν ταυτίσεις, η λέξη αφαιρείται. Αν ενεργοποιηθεί η επιλογή φλοιού nocaseglob, η ταύτιση γίνεται χωρίς δι'ακριση πεζών ή κεφαλαίων χαρακτήρων.

Όταν ένα πρότυπο χρησιμοποιείται για δημιουργία ονομάτων αρχείων, ο χαρακτήρας "." στην αρχή ενός ονόματος αρχείου ή αμέσως μετά μια κάθετο πρέπει να ταυτίζεται ρητά, εκτός να έχει τεθεί η επιλογή  dotglob. Κατά τη ταύτιση ονομάτων αρχείων, ο χαρακτήρας της καθέτου  πάντα ταυτίζεται ρητά. Στις άλλες περιπτώσεις ο χαρακτήρας "." δεν αντιμετωπίζεται ιδιαίτερα.

Η μεταβλητή φλοιού GLOBIGNORE μπορεί να χρησιμοποιηθεί για τον περιορισμό τοτ συνόλου των ονομάτων που ταυτίζονται με ένα πρότυπο. Αν η GLOBIGNORE έχει οριστεί, κάθε όνομα αρχέιου που ταιριάζει στη ταύτιση αλλά ταιριάζει και με κάποιο πρότυπο της GLOBIGNORE αφαιρείται από τη λίστα των ατυτίσεων. Τα ονόματα αρχείων . και .. αγνοούνται πάντα, ακόμη αι αν η GLOBIGNORE έχει οριστεί. Όμως, ο ορισμός της GLOBIGNORE έχει ως παρεπόμενο την ενεργοποίηση της επιλογής φλοιού dotglob, έτσι ώστε όλα τα ονόματα που αρχίζουν με "." θα ταυτιστούν. Για να έχετε τη προηγούμενη συμπεριφορά αγνόησης των ονομάτων αρχείων που ξεκινούν με ".", πρέπει να βάλετε το ".*" στα πρότυπα της GLOBIGNORE. Η επιλογή dotglob είναι ανενεργή όταν η GLOBIGNORE δεν είναι ορισμένη.


3.5. Ψευδώνυμα

3.5.1. Τι είναι τα ψευδώνυμα;

Ένα ψευδώνυμο επιτρέπει ένα αλφαριθμητικό να αντικαθιστά μια λέξη όταν αυτή είναι η πρώτη λέξη μας απλής εντολής. Ο φλοιός διατηρεί μια λίστα ψευδωνύμων που μπορεί να τροποποιηθεί με τις εσωτερικές εντολές alias και unalias. Η εντολή alias χωρίς επιλογές εμφανίζει τη λίστα των ψευδωνύμων που είναι γνωστά στον τρέχοντα φλοιό.

 
franky: ~> alias
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias PAGER='less -r'
alias Txterm='export TERM=xterm'
alias XARGS='xargs -r'
alias cdrecord='cdrecord -dev 0,0,0 -speed=8'
alias e='vi'
alias egrep='grep -E'
alias ewformat='fdformat -n /dev/fd0u1743; ewfsck'
alias fgrep='grep -F'
alias ftp='ncftp -d15'
alias h='history 10'
alias fformat='fdformat /dev/fd0H1440'
alias j='jobs -l'
alias ksane='setterm -reset'
alias ls='ls -F --color=auto'
alias m='less'
alias md='mkdir'
alias od='od -Ax -ta -txC'
alias p='pstree -p'
alias ping='ping -vc1'
alias sb='ssh blubber'
alias sl='ls'
alias ss='ssh octarine'
alias sss='ssh -C server1.us.xalasys.com'
alias sssu='ssh -C -l root server1.us.xalasys.com'
alias tar='gtar'
alias tmp='cd /tmp'
alias unaliasall='unalias -a'
alias vi='eval `resize`;vi'
alias vt100='export TERM=vt100'
alias which='type'
alias xt='xterm -bg black -fg white &'
 
franky ~>

Τα ψευδώνυμα είναι χρήσιμα για τον ορισμό προεπιλεγμένων μορφών σε εντολές που διατίθενται σε πολλές εκδόσεις ή για τον ορισμό των προκαθορισμένων επιλογών σε μια εντολή. Μια άλλη επιλογή είναι η παράβλεψη συνηθισμένων αναγραμματσμών στη πληκτρολόγηση.

Η πρώτη λέξη σε κάθε απλή εντολή, αν δεν έχει εισγωγικά, ελέγχεται για ψευδώνυμα. Αν είναι τέτοιο, τότε αντικαθίσταται. Το ψευδώνυμο και το κείμενο αντικατάστασης μπορεί να περιέχει οποιαδήποτε νόμιμη είσοδο φλοιού, συμπεριλαμβανομένων και μεταχαρακτήρων φλοιού, με την εσξίρεση οτι ένα ψευδώνυμο δεν μπορεί να περιέχει "=". Η πρώτη λέξη του κειμένου αντικατάστασης ελέγχεται για ψευδώνυμα, με εξαίρεση τον εαυτό της. Αυτό σημαίνει οτι μπορούμε να αντιστοιχίσουμε το ls στο ls -F, λόγου χάρη, και το Bash δεν θα προχωρήσει σε αναδρομική αντικατάσατση του ψευδωνύμου. Αν ο τεέυταίος χαρακτήρας του ψευδωνύμου είναι κενό ή tab, τότε η επόμενη λέξη στη γραμμή εντολών ελέγχεται για ψευδώνυμα.

Τα ψευδώνυμα δεν επεκτείνονται όταν ο φλοιός δεν είναι διαλογικός, εκός και αν έχει ενεργοποιηθεί η ειλογή expand_aliases μέσω της ενσωματωμένης εντολής shopt.


3.5.2. Δημιουργία και διαγραφή ψευδωνύμων

Τα ψευδώνυμα δημιουργούνται με την εσωτερική εντολή alias. Για μόνιμη χρήση εισάγετε τα ψευδώνυμα σε ένα από τα αρχεία ρύθμισης του φλοιού. Αν εισάγετε ένα ψευδώνυμο στη γραμμή εντολών τότε αυτό είνα γνωστό μόνο στο τρέχοντα φλοιό..

 
franky ~> alias dh='df -h'
 
franky ~> dh
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda7             1.3G  272M 1018M  22% /
/dev/hda1             121M  9.4M  105M   9% /boot
/dev/hda2             13G  8.7G  3.7G  70% /home
/dev/hda3             13G  5.3G  7.1G  43% /opt
none                  243M     0  243M   0% /dev/shm
/dev/hda6             3.9G  3.2G  572M  85% /usr
/dev/hda5             5.2G  4.3G  725M  86% /var
 
franky ~> unalias dh
 
franky ~> dh
bash: dh: command not found
 
franky ~>

Το Bash πάντα διαβάζει τουλάχιστο μια πλήρη γραμμή εισόδου πριν την εκτέλεση οποιασδήποτε εντολής της γραμμής. Τα ψευδώνυμα επεκτείνονται όταν διαβάζεται μια γραμμή εντολών, όχι όταν εκτελείται. Γι΄αυτό το λόγο ένας ορισμός ψευδωνύμου στην ίδια γραμμή με η χρήση του δεν μπορεί να λειτουργήσει. Αυτή η συμπεριφορά ισχύει και για την εκτέλεση συναρτήσεων. Τα ψευδώνυμα επεκτείνονται κατά την ανάγνωση του ορισμούκαι όχι κατά την εκτέλεση της συνάρτησης, επειδή ο ορισμός της συνάρτησης είναι μια σύνθετη εντολή. Ως συνέπεια, ψεδυδώνυμα που ορίζονται σε μια συνάρτηση δεν είναι διαθέσιμα παρά μόνο μετά την εκτέλεση της συνάρτησης. Για να είμαστε ασφαλείς, πάντα δηλώνουμε τα ψευδώνυμα σε ξεχωριστές γραμμές, και δεν χρησιμοποιούμε την εντολή alias σε σύνθετες εντολές.

Τα ψευδύνυμα δεν κληρονομούνται σε θυγατρικές διεργασίες. Ο φλοιός Bourne (sh) δεν αναγνωρίζει ψευδώνυμα.

Περισσότερα για τις συναρτήσεις στο Κεφάλαιο 11.

Tip

Οι συναρτήσεις είναι ταχύτερες

Τα ψευδώνυμα αναλύονται μετά τις συναρτήσεις και γι' αυτό υπάρχει μεγαλύτερη καθυστέρηση. Αν και τα ψευδώνυμα είναι ευκολότερα στη κατανόηση, οι συναρτήσεις φλοιού προτιμώνται  σχεδόν σε κάθε περιπτωση.


3.6. Άλλες επιλογές του Bash

3.6.1. Εμφάνιση επιλογών

Ήδη έχουμε συζητήσει μερικές επιλογές του Bash που είναι χρήσιμες για την εκσφαλμάτωση σεναρίων. Σε αυτή την ενότητα, θα δούμε σε μεγαλύτερο βάθος στις επιλογές του Bash.

Με την επιλογή -o στην εντολή set εμφανίζονται όλες οι επιλογές:

 
willy:~> set -o
allexport              off
braceexpand            on
emacs                  on
errexit                off
hashall                on
histexpand             on
history                on
ignoreeof              off
interactive-comments   on
keyword                off
monitor                on
noclobber              off
noexec                 off
noglob                 off
nolog                  off
notify                 off
nounset                off
onecmd                 off
physical               off
posix                  off
privileged             off
verbose                off
vi                     off
xtrace                 off

Δείτε στις σελίδες πληροφόρησης του Bash, Shell Built-in Commands->The Set Built-in fγια μια περιγραφή κάθε επιλογής. Πολλές επιλογές έχουν συντομέυσεις ενός χαρακτήρα: για παράδειγμα, η επιλογή xtrace είναι ισοδύναμη με την set -x.


3.6.2. Τροποποίηση επιλογών

Οι επιλογές φλοιού μπορούν να ρυθμιστούν διαφορετικά από τη προεπιλογή είτε κατά τη κλήση του φλοιού, ή κατά την εκτέλεσή του. Αυτές οι τροποποιήσεις μπορούν να περιληφθούν στα αρχεία ρύθμισης του φλοιού.

Η ακόλουθη εντολή εκτελεί ένα σενάριο σε κατάσταση συμβατή με POSIX.

 
willy:~/scripts> bash --posix script.sh

Για προσωρινή αλλαγή, ή για χρήση σε ένα σενάριο, καλύτερα να χρησιμοποιήσουμε την εντολή set. Χρησιμοποιούμε - (μείον) για ενεργοποίηση επιλογής + για απανεργοποίηση.

 
willy:~/test> set -o noclobber
 
willy:~/test> touch test
 
willy:~/test> date > test
bash: test: cannot overwrite existing file
 
willy:~/test> set +o noclobber
 
willy:~/test> date > test

Το παραπάνω παράδειγμα επιδεικνύει την επιλογή noclobber, που αποτρέπει την τροποποίηση υπαρχόντων αρχείων από τις λειτουργίες ανακατεύθυνσης. Το ίδιο συμβαίνει με επιλογές ενός χαρακτήρα, λόγου χάρη το -u, που χειρίζεται τις μη ορισμένες μεταβλητές σαν σφάλμα, και τερματίζει έναν μη-διαλογικό φλοιό μόλις συναντήσει τέτοιο σφάλμα.

 
willy:~> echo $VAR
 
 
willy:~> set -u
 
willy:~> echo $VAR
bash: VAR: unbound variable

Αυτή η επιλογή είναι επίσης χρήσιμη για την ανίχνευση λανθασμένων εκχωρλησεων σε μεταβλητές: το ίδιο σφάλμα θα προκληθεί, λόγου χάρη, όταν εκχωρείται ένα αλφαριθμητικό σε μια μεταβλητή που έχει δηλωθεί ως ακέραια.

Ένα τελευταίο παράδειγμα, δείχνει την χρήση της επιλογής noglob, που αποτρέπει την επέκταση των ειδκών χαρακτήρων.

 
willy:~/testdir> set -o noglob
 
willy:~/testdir> touch *
 
willy:~/testdir> ls -l *
-rw-rw-r--    1 willy    willy        0 Feb 27 13:37 *

3.7. Περίληψη

Το περιβάλλον του Bash μπορεί να διαμορφωθεί είτε καθολικά ή ανά χρήστη. Για τη διαμόρφωση χρησιμοποιούνται διάφορα αρχεία ρυθμίσεων.

Τα αρχεία αυτά περιέχουν επιλογές φλοιού, ορισμούς μεταβλητών, ορισμούς συναρτήσεων και διάφορα άλλα δομικά στοιχεία που μας επιτρέπουν να δημιουργήσουμε το περιβάλλον που μας βολεύει.

Εκτός από τις δεσμευμένες λέξεις του των φλοιών Βourne και Bash, τα ονόματα μεταβλητών μπορούν αν επιλεγούν ελεύθερα.

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

Το Bash, για να καθορίσει ποιές εντολές θα εκτελέσεθ, χρησιμοποιεί διάφορες μεθόδους επέκτασης των λέξεων (συμβόλων) της γραμμής εντολών.


3.8. Ασκήσεις

Γι' αυτή την άσκηση, θα χρειαστεί να διβάσετε τις σελίδες του εγχειριδίου (man) του useradd, γιατί θα χρησιμοποιήσουμε τον κατάλογο /etc/skel για να αποθηκεύσουμε τα προεπιλεγμένα αρχεία ρυθμίσεων, που αντιγράφονται στον οικείο κατάλογο κάθε νέου χρήστη.

Πρώτα θα εκτελέσουμε μερικές ασκήσεις ορισμού και εμφάνισης μεταβλητών.

1.      Δημιουργείστε 3 μεταβλητές, VAR1, VAR2 και VAR3. Αρχικοποιείστε τις με τιμές "thirteen", "13" και  "Happy Birthday" αντίστοιχα.

2.      Εμφανίστε τις τιμές των μεταβλητών.

3.      Είναι τοπικές ή καθολικές μεταβλητές;

4.      Διαγράψτε την VAR3.

5.      Μπορείτε να δείτε τις δύο απομένουσες μεταβλητές σε νέο παράθυρο τερματικού;

6.      Τροποποιείστε το αρχείο /etc/profile έτσι ώστε όλοι οι χρήστες να καλωσορίζονται κατά την σύνδεση (ελέγξτε το).

7.      Για τον λογαριασμό root, ορίστε τη προτροπή σε κάτι σαν "Danger!! root is doing stuff in \w", κατά προτίμηση σε ένα έντονο χρώμα όπως κόκκινο ή σε reverse video.

8.      Βεβαιωθείτε οτι οι νέοι χρήστες λαμβάνουν μια προσωποποιημένη προτροπή που τους πληροφορεί σε ποιό σύστημα και ποιό κατάλογο βρίσκονται. Ελέγξτε τις αλλαγές σας προσθέτοντας ένα νέο όνομα χρήστη και συνδεθείτε με αυτό..

9.      Γράψτε ένα σενάριο όπου δίνετε δύο ακέραιες τιμές σε δύο μεταβλητές. Το σενάριο πρέπει να υπολογίζει το εμβαδό ενός ορθογωνίου. Πρέπει να συνοδεύεται από σχόλια και να εμφανίζει όμορφα το αποτέλεσμα.

Μη ξεχάσετε να αλλάζετε τα δικαιώματα στα σενάρια με chmod !


Κεφάλαιο 4. Κανονικές εκφράσεις

Σε αυτό το κεφάλαιο θα συζητήσουμε:

         Τη χρήση κανονικών εκφράσεων

         Τους μεταχαρακτήρες κανονικών εκφράσεων

         Την εύρεση προτύπων σε αρχεία ή έξοδο

         Τις κλάσεις χαρακτήρων και το εύρος τους στο Bash


4.1. Κανονικές εκφράσεις

4.1.1. Τι είναι οι κανονικές εκφράσεις;

Μια  κανονική έκφραση είναι ένα πρότυπο που περιγράφει ένα σύνολο αλφαριθμητικών (συμβολοσειρών). Οι κανονικές εκφράσεις δομούνται κατ'αναλογία με τις αριθμητικές εκφράσεις, χρησιμοποιώντας διάφορους τελεστές για το συνδυασμό μικρότερων εκφράσεων.

Τα στοιχειώδη δομικά στοιχεία είναι κανονικές εκφράσεις που ταυτίζονται με απλούς χαρακτήρες.Οι περισσότεροι χαρακτήρες, όλα τα γράμματα και τα ψηφία, είναι κανονικές εκφράσεις που ταυτίζονται με το ευατό τους, Οι χαρακτήρες με ειδική σημασία, μπορούν να ακυρωθούν αν προηγείται ένα backslash.


4.1.2. Μεταχαρακτήρες κανονικών εκφράσεων

Μια κανονική έκφραση μπορεί να ακολουθείται από κάποιο τελεστή επανάληψης (μεταχαρακτήρα):

Πίνακς 4-1. Τελεστές κανονικών εκφράσεων

Τελεστής 

Αποτέλεσμα

.

Ταυτίζεται με οποιοδήποτε μεμονωμένο χαρακτήρα.

?

Ο χαρακτήρας που προηγείται είναι προαιρετικός και θα ταυτιστεί το πολύ μία φορά.

*

Ο χαρακτήρας που προηγείται θα ταυτιστεί μηδέν ή περισσότερες φορές.

+

Ο χαρακτήρας που προηγείται θα ταυτιστεί μία ή περισσότερες φορές.

{N}

Ο χαρακτήρας που προηγείται θα ταυτιστεί ακριβώς Ν φορές.

{N,}

Ο χαρακτήρας που προηγείται θα ταυτιστεί Ν ή περισσότερες φορές.

{N,M}

Ο χαρακτήρας που προηγείται θα ταυτιστεί Ν ή περισσότερες φορές, αλλά όχι περισσότερες από Μ.

-

Παριστά το εύρος αν δεν είναι πρώτος ή τελευταίος αρακτήρας, ή τελευταίος χαρακτήρας σε λίστα.

^

Ταυτίζει την αρχή μιας γραμμής. Επίσης παριστά τους χαρακτήρες που δεν περιέχονται σε μια λίστα.

$

Ταυτίζει το τέλος μιας γραμμής.

\b

Ταυτίζει το τέλος μιας λέξης.

\B

Ταυτίζει άδεια συμβολοσειρά που δεν είναι τέλος λέξης.

\<

Ταυτίζει άδεια συμβολοσειρά στην αρχή μιας λέξης.

\>

Ταυτίζει άδεια συμβολοσειρά στο τέλος μιας λέξης..

Δύο κανονικές εκφράσεις μπορεί να συνενωθούν. Η κανονική έκφραση που προκύπτει ταυτίζεται με οποιαδήποτε συμβολοσειρά προκύπτει από τη συνένωνη δύο έγκυρων συμβολοσειρών που αντίστοιχα ταυτίζονται με τις επιμέρους συμβολοσειρές.

Δυο κανονικε εκφράσεις μπορεί να συνδυαστούν με τον τελεστή εναλλαγής "|". Η νέα κανονική έκφραση ταυτίζεται με οποιαδήποτε από τις υπιο-εκφράσεις.

Η επανάληψη προηγείται της συνένωσης, που με τη σειρά της προηγείται της εναλλαγής. Η χρήση παρενθέσεων αλλάξει τους κανόνες προτεραιότητας. 


4.1.3. Βασικές και εκτεταμένες κανονικές εκφράσεις

Στις βασικές κανονικές εκφράσεις οι μεταχαρακτήρες "?", "+", "{", "}", "|", "(", και ")" δεν έχουν ειδική σημασία. Πρέπει να χρησιμοποιηθούν οι "\?", "\+", "\{", "\}, "\|", "\(", and "\)".

Ελέγξτε τη τεκμηρίωση του συστήματός σας για να δείτε αν οι εντολές σας χρησιμοποιούν βασικές και εκταταμένες κανονικές εκφράσεις.


4.2. Παραδείγματα με το grep

4.2.1. Τι είναι το grep?

Η εντολή grep αναζητά σε αρχεία κειμένου γραμμές που περιέχουν ένα πρότυπο. Όταν βρίσκει μια ταύτιση, αντιγράφει τη συκεκριμένη γραμμή στη πρότυπη έξοδο (ως προεπιλογή) ή σε όποια άλλη άξοδο ορίζουν οι επιλογές της εντολής.

Αν και η grep υποθέτει ταύτιση σε κείμενο, δεν έχει συγκεκριμένο όριο στο μέγεθος γραμμής, πέρα από τη διαθέσιμη μνήμη, και μπορεί να ταυτίσει πρότυπα οποιουδήποτε μεγέθους.Αν το τελικό byte της γραμμής εισόδου δεν είναι newline, η grep σιωπηρά προσθέτει ένα. Αφού η αλλαγή γραμμής είναι διαχωριστικό προτύπων και γραμμών, δεν υπάρχει τρόπος να ταυτίσουμε χαρακτήρες αλλαγής γραμμής..

Μερικά παραδείγματα:

 
cathy ~> grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
 
cathy ~> grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
12:operator:x:11:0:operator:/root:/sbin/nologin
 
cathy ~> grep -v bash /etc/passwd | grep -v nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
news:x:9:13:news:/var/spool/news:
mailnull:x:47:47::/var/spool/mqueue:/dev/null
xfs:x:43:43:X Font Server:/etc/X11/fs:/bin/false
rpc:x:32:32:Portmapper RPC user:/:/bin/false
nscd:x:28:28:NSCD Daemon:/:/bin/false
named:x:25:25:Named:/var/named:/bin/false
squid:x:23:23::/var/spool/squid:/dev/null
ldap:x:55:55:LDAP User:/var/lib/ldap:/bin/false
apache:x:48:48:Apache:/var/www:/bin/false
 
cathy ~> grep -c false /etc/passwd
7
 
cathy ~> grep -i ps ~/.bash* | grep -v history
/home/cathy/.bashrc:PS1="\[\033[1;44m\]$USER is in \w\[\033[0m\] "
 

Με τη πρώτη εντολή, η χρήστης cathy εμφανίζει τις γραμμές του αρχείου /etc/passwd που περιέχουν τη συμβολοσειρά root.

Μετά εμφανίζει τις γραμμές με αριθμό γραμμής μπροστά.

Με τη τρίτη εντολή ελέγχει ποιοί χρήστες δεν χρησιμοποιούν bash, αλλά οι λογαριασμοί με φλοιό nologin δεν εμφανίζονται..

Κατόπιν μετρά τους λογαριασμούς που έχουν ως φλοιό το /bin/false.

Η τελευταία εντολή εμφανίζει τις γραμμές όλων των αρχείων του οικείου καταλόγου της που ξεκινούν με ~/.bash, εξαιρούμενης τη ταύτισης με το πρότυπο history, ώστε να εξαιρεθούν οι ταυτίσεις από το αρχείο ~/.bash_history που μπορεί να περιέχουν το ίδιο πρότυπο, με πεζά ή κεφαλαία γράμματα. Σημειώστε οτι αναζητούμε τη συμβολοσειρά "ps", και όχι την εντολή  ps.

Τώρα ας δούμε τι μπορούμε να κάνουμε με τη grep, με τη χρήση κανονικών εκφράσεων.


4.2.2. Grep και κανονικές εκφράσεις

Note

Αν δεν βρίσκεστε σε Linux

 

Σε αυτά τα παραδείγματα χρησιμοποιούμε τη GNU grep, η οποία υποστηρίζει εκτεταμένες κανονικές εκφράσεις. H GNU grep είναι η προεπιλογή στα συστήματα Linux. Αν εργάζεστε σε άλλου τύπου σύστημα Unix, ελέγξτε την έκδοση που χρησιμοποιείτε με την επιλογή  -V. Η GNU grep μπορεί να μεταφορτωθεί από τον ιστοτόπο http://gnu.org/directory/.


4.2.2.1. Άγκυρες γραμμών και λέξεων 

Από το προηγούμενο παράδειγμα, τώρα θέλουμε να εμφανίσουμε αποκλειστικά τισ γραμμές που αρχίζουν με "root":

 
cathy ~> grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash

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

 
cathy ~> grep :$ /etc/passwd
news:x:9:13:news:/var/spool/news:

Για να ελέγξουμε αν η μεταβλητή PATH εξήχθη στο αρχείο ~/.bashrc, πρώτα επιλέγουμε τις γραμμές με "export" και μετά αναζητούμε τη συμβολοσειρά "PATH", ως αρχή λέξης, έτσι ώστε να μην εμφανιστούν διαδομές όπως η MANPATH και άλλες:

 
cathy ~> grep export ~/.bashrc | grep '\<PATH'
  export PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"

Παρόμοια, το \> ταυτίζει συμβολοσειρά με το τέλος λέξης.

Αν θέλετε να βρείτε μια συμβολοσειρά που αποτελεί ξαχωριστή λέξη (μεταξύ κενών), είναι καλύτερα να χρησιμοπιήσετε την επιλογή -w, όπως σε αυτό το παράδειγμα όπου εμφανίζουμε πληροφορίες για το διαμέρισμα root:

 
cathy ~> grep -w / /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1

Άν δεν χρησιμοποιηθεί αυτή η επιλογή, θα εμφανιστούν όλες οι γραμμές του συστήματος αρχείων..


4.2.2.2. Κλάσεις χαρακτήρων

Μια  έκφραση ορθογώνιων παρενθέσεων είναι μια λίστα χαρακτήρων που περικλείονται σε "[" και "]". Ταυτίζει κάθε απλό χαρακτήρα της λίστας. Αν ο πρώτος χαρακτήρας σε αυτή τη λίστα είναι το "^", τότε ταυτίζει κάθε χαρακτήρα ΔΕΝ είναι στη λίστα. Για παράδειγμα, η κανονική έκφραση "[0123456789]" ταυτίζει κάθε απλό ψηφίο..

Μέσα σε μια έκφραση ορθογώνιων παρενθέσεων, μια έκφραση εύρους αποτελείται από δύο χαρακτήρες που χωρίζονται με "-". Ταυτίζει κάθε χαρακτήρα που βρίσκεται μεταξύ των δύο χαρακτήρων , συμπεριλαμβανομένων των άκρων. Χρησιμοποιείται η τοπική κωδικοποίηση χαρακτήρων. Για παράδειγμα, στη προεπιλεγμένη κωδικοποίηση της  C, η έκφραση "[a-d]" ισοδυναμεί με την "[abcd]". Πολλές τοπικές κωδικοποιήσεις ταξινομούν τους χαρακτήρες με λεξικογραφική σειρά, και σε αυτές τις κωδικοποιήσεις η έκφραση "[a-d]" μπορεί να ισοδυναμεί με  την "[aBbCcDd]", για παράδειγμα. Για να διασφαλίσουμε την παραδοσιακή διερμηνεία των εκφράσεων, μπορούμε να χρησιμοποιήσουμε τη κωδικοποίηση της C θέτοντας τις μεταβλητές περιβάλλοντος LC_COLLATE ή LC_ALL στην τιμή "C".

Τελικά, μερικές ονομασμένες κλάσεις χαρακτήρων είναι γνωστές στις εκφράσεις ορθογώνιων παρενθέσεων. Δείτε τις σελίδες εγχειριδίου ή πληροφοριών της εντολής grep σχετικά με τις προκαθορισμένες κλάσεις χαρακτήρων.

 
cathy ~> grep [yf] /etc/group
sys:x:3:root,bin,adm
tty:x:5:
mail:x:12:mail,postfix
ftp:x:50:
nobody:x:99:
floppy:x:19:
xfs:x:43:
nfsnobody:x:65534:
postfix:x:89:
 
cathy ~> ls *[1-9].xml
app1.xml  chap1.xml  chap2.xml  chap3.xml  chap4.xml

Στο παράδειγμα, πρώτα εμφανίζονται όλες οι γραμμές που περιέχουν "y" ή "f". Κατόπιν υπάρχει ένα παράδειγμα χρησης του έυρους χαρακτήρων με την εντολή  ls.


4.2.2.3. Μπαλαντέρ

Χρησιμοποιούμε το "." για τη ταύτιση οποιυδήποτε απλού χαρακτήρα. Αν θέλετε να εμφανίσετε μια λίστα όλων των Αγγλικών λέξεων πέντε χαρακτήρων που ξεκινούν με "c" και τελιώνουν με "h" (καλό για σταυρόλεξα) τότε:

 
cathy ~> grep '\<c...h\>' /usr/share/dict/words
catch
clash
cloth
coach
couch
cough
crash
crush

Αν θέλετα να εμφανίσετε γραμμές που περιέχουν την τελεία (κυριολεκτικά) χρησιμοποιείστε την επιλογή -F της grep.

Για τη ταύτιση πολλών χαρακτήρων, χρησιμοποιούμε τον αστερίσκο. Αυτό το παράδειγμα επιλέγει όλες τις λέξεις που αρχίζουν με "c" και τελειώνουν με "h" από το λεξικό του συστήματος:

 
cathy ~> grep '\<c.*h\>' /usr/share/dict/words
caliph
cash
catch
cheesecloth
cheetah
--output omitted--

Αν θέλετε να βρείτε τον αστερίσκο (κυριολεκτικά) σε ένα αρχείο ή έξοδο, χρησιμοποιείστε τη grep -F:

 
cathy ~> grep * /etc/profile
 
cathy ~> grep -F '*' /etc/profile
for i in /etc/profile.d/*.sh ; do

4.3. Ταύτιση προτύπων με το Bash

4.3.1. Διαστήματα χαρακτήρων

Εκτός απί τη grep και τις κανονικές εκφράσεις, υπάρχουν αρκετές δυνατότητες ταύτισης προτύπων στον ίδιο το φλοιό, χωρίς να απαιτείται η χρήση εξωτερικού προγράμματος.

Οπως ήδη γνωρίζετε, ο αστερίσκος (*) και το ερωτηματικό (?) ταυτίζουν οποιαδήποτε συμβολοσειρά και οποιοδήποτε χαρακτήρα, αντίστοιχα. Για κυριολεκτική ταύτιση, αυτοί οι χαρακτήρες πρέπει να περιβληθούν με διπλά εισαγωγικά:

 
cathy ~> touch "*"
 
cathy ~> ls "*"
*

Όμως μπορείτε να χρησιμοποιήσετε ορθογώνιες παρενθέσεις για τη ταύτιση καθενός από τους περικλειόμενους χαρακτήρες ή για ταύτιση σε κάποιο εύρος χαρακτήρων, όταν έχουμε ζεύγη χαρακτήρων χωρισμένα με "-". Ένα παράδειγμα::

 
cathy ~> ls -ld [a-cx-z]*
drwxr-xr-x    2 cathy    cathy          4096 Jul 20  2002 app-defaults/
drwxrwxr-x    4 cathy    cathy          4096 May 25  2002 arabic/
drwxrwxr-x    2 cathy    cathy          4096 Mar  4 18:30 bin/
drwxr-xr-x    7 cathy    cathy          4096 Sep  2  2001 crossover/
drwxrwxr-x    3 cathy    cathy          4096 Mar 22  2002 xml/

Αυτή η εντολή εμφανίζει τα αρχεία του οικείου καταλόγου της cathy που ξεκινούν με "a", "b", "c", "x", "y" ή "z".

Αν ο πρώτος χαρακτήρας μέσα στις ορθογώνιες παρενθέσεις είναι "!" ή "^", τότε ταυτίζονται οι χαρακτήρες που δεν περιλαμβάνονται. Για να ταυτίσουμε το μείον ("-"), μπορούμε να τη περιλάβουμε ως πρώτο ή τελευταίο χαρακτήρα του συνόλου. Για τον υπολογισμό του εύρους χρησιμοποιείται η τοπική κωδικοποίηση χαρακτήρων. Για παράδειγμα, στη προεπιλεγμένη κωδικοποίηση της  C, η έκφραση "[a-d]" ισοδυναμεί με την "[abcd]". Πολλές τοπικές κωδικοποιήσεις ταξινομούν τους χαρακτήρες με λεξικογραφική σειρά, και σε αυτές τις κωδικοποιήσεις η έκφραση "[a-d]" μπορεί να ισοδυναμεί με  την "[aBbCcDd]", για παράδειγμα. Για να διασφαλίσουμε την παραδοσιακή διερμηνεία των εκφράσεων, μπορούμε να χρησιμοποιήσουμε τη κωδικοποίηση της C θέτοντας τις μεταβλητές περιβάλλοντος LC_COLLATE ή LC_ALL στην τιμή "C".


4.3.2. Κλάσεις χαρακτήρων

Οι κλάσεις χαρακτήρων μπορούν να καθοριστούν μέσα σε ορθογώνιες παρενθέσεις, με τη σύνταξη [:CLASS:], όπου το CLASS ορίζεται στο πρότυπο POSIX και έχει μια από τις τιμές

"alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph", "lower", "print", "punct", "space", "upper", "word" ή "git".

Μερικά παραδείγματα:

 
cathy ~> ls -ld [[:digit:]]*
drwxrwxr-x    2 cathy  cathy          4096 Apr 20 13:45 2/
 
cathy ~> ls -ld [[:upper:]]*
drwxrwxr--    3 cathy   cathy           4096 Sep 30  2001 Nautilus/
drwxrwxr-x    4 cathy   cathy           4096 Jul 11  2002 OpenOffice.org1.0/
-rw-rw-r--    1 cathy   cathy         997376 Apr 18 15:39 Schedule.sdc

Όταν η επιλογή φλοιού extglob ενεργοποιηθεί (μέσω της εσωτερικής εντολής shopt), τότε αναγνωρίζονται αρκετές λειτουργίες εκετατμένης ταύτισης προτύπων. Διαβάστε περισσότερα στις σελίδες πληροφόρησης του Bash, ενότητα Basic shell features->Shell Expansions->Filename Expansion->Pattern Matching.


4.4. Περίληψη

Οι κανονικές εκφράσεις είναι ισχυρά εργαλεία για την επιλογή συγκεριμένων γραμμών από αρχεία ή την έξοδο. Πολλές εντολές και εφαρμογές του UNIX χρησιμοποιούν κανονικές εκφράσεις, όπως τα vim, perl, η βάση δεδομένων PostgreSQL κλπ. Μπορούν να εισχθούν σε οποιαδήποτε γλώσσα ή εφαρμογή με τη βοήθεια εξωτερικών βιβλιοθηκών, και ακόμη είναι διαθέσιμες και σε μη-UNIX συστήματα. Για παράδειγμα, οι κανονικές εκφράσεις χρησιμοποιούνται στο λογιστικό φύλλο Excell του πακέτου MicroSoft Windows Office. Σε αυτό το κεφάλαιο προσεγγίσαμε την εντολή grep, που είναι απαραίτητη σε κάθε περιβάλλον UNIX.

Note

 Η εντολή grep μπορεί να κάνει πολύ περισσότερα από τις λίγες εργασίες που συζητήσαμε εδώ. Τη χρησιμοποιήσαμε μόνο ως παράδειγμα χειρισμού κανονικών εκφράσεων. Η έκδοση GNU grep συνοδεύεται από μεγάλη τεκμηρίωση που σας συνιστούμε να διαβάσετε!

Το Bash έχει ενσωματωμένα χαρακτηριστικά για ταύτιση προτύπων και μπορεί να αναγνωρίσει κλάσεις και εύρη χαρακτήρων. 


4.5. Ασκήσεις

Αυτές οι ασκήσεις θα σας βοηθήσουν να χειριστείτε κανονικές εκφράσεις.

1.      Εμφανίστε μια λίστα με όλους τους χρήστες στο σύστημά σας που έχουν το Bash ως προεπιλεγμένο φλοιό.

2.      Από το αρχείο /etc/group, εμφανίστε όλες τις γραμμές που περιέχουν τη συμβολοσειρά "daemon".

3.      Από το ίδιο αρχείο εμφανίστε όλες τις σειρές που δεν περιέχουν αυτή τη συμβολοσειρά.

4.      Εμφανίστε τις πληροφορίες του localhost από το αρχείο /etc/hosts, εμφανίστε τους αριθμούς γραμμών όπου υπάρχει η συμβολοσειρά και μετρήστε το πλήθος των ταυτίσεων.

5.      Εμφανίστε μια λίστα υποκαταλόγων του καταλόγου /usr/share/doc που περιέχουν πληροφορίες για φλοιούς.

6.      Πόσα αρχεία README περιέχουν αυτοί οι υποκατάλογοι; Μη μετρήσετε ονόματα στη μορφή "README.a_string".

7.      Με τη βοήθεια της grep κάντε μια λίστα των αρχείων του οικείου καταλόγου σας τα οποία τροποποιήθηκαν τις τελευταίες 10 ώρες, αλλά μην περιλάβετε τους υποκαταλόγους.

8.      Βάλτε τις εντολές σε ένα σενάριο που θα παράγει ένα κατανοητό αποτέλεσμα.

9.      Μπορείτε, με τη χρήση της grep να βρείτε εναλλακτική λύση για την εντολή wc -l;

10.  Με τη χρήση ενός πίνακα του συστήματος αρχείων (πχ το /etc/fstab), εμφανίστε τις τοπικές συσκευές δίσκων.

11.  Δημιουργείστε ένα σενάριο που ελέγχει αν υπάρχει κάποιος χρήστης στο αρχείο /etc/passwd. Προς το παρόν, μπορείτε να ορίσετε το όνομα του χρήστη μέσα στο σενάριο, δε χρειάζεται να δουλέψετε με ορίσματα και εντολές συνθήκης.

12.   Εμφανίστε τα αρχεία ρύθμισης στο κατάλογο /etc που περιέχουν αριθμούς στα ονόματά τους.


Κεφάλαιο 5. Ο συντάκτης ροής GNU sed 

Στο τέλος αυτού του κεφαλαίου θα γνωρίζετε τα παρακάτω θέματα:

         Τι είναι ο sed;

         Διαλογική χρήση του sed

         Κανονικές εκφράσεις και σύνταξη ροής

         Χρήση εντολών sed σε σενάρια

Note

Πρόκειται για εισαγωγή

 

Το κείμενο που ακολουθεί απέχει πολύ από το να είναι πλήρης και οριστικός οδηγός χρήσης του sed. Το κεφάλαιο αυτό περιλαμβάνεται για να μπορέσουμε να δείξουμε μερικά ενδιαφέροντα θέματα σχετικά με τα σενάρια σε επόμενα κεφάλαια, και επειδή κάθε ισχυρός χρήστης Linux πρέπει να γνωρίζει ορισμένα βασικά για αυτόν τον συντάκτη.

Για λεπτομερείς πληροφορίες, αναφερθείτε στις σελίδες πληροφόρησης και εγχειριδίου του sed.


5.1. Εισαγωγή

5.1.1. Τι είναι ο sed;

Ένας συντάκτης ροής (Stream EDitor) χρησιμοποιείται για την τροποποίηση κειμένου κατά την ανάγνωσή του από αρχείο ή από σωλήνωση. Το αποτέλεσμα αποστέλεται στη πρότυπη έξοδο. Η σύνταξη της εντολής sed δεν προβλέπει αρχείο εξόδου, αλλά το αποτέλεσμα μπορεί να αποθηκευτεί σε αρχείο με ανακατεύθυσνη της εξόδου. Ο συντάκτης δεν τροποποιεί την αρχική εσίσοδο.

Αυτό που ξεχωρίζει τον sed από άλλους συντάκτες, όπως ο vi ή ο ed, είναι η δυνατότητά του να φιλτράρει κείμενο που λαμβάνει από σωλήνωση. Δεν χρειάζεται να διαδράτε με τον συντάκτη, κατά την εκτέλεση, γι' αυτό το λόγο ο sed μερικές φορές λέγεται και συντάκτης δέσμης (batch editor). Αυτό το χαρακτηριστικό επιτρέπει τη χρήση εντολών τροποποίησης αρχείων μέσα σε σενάρια, πράγμα που διευκολύνει πολύ σε επαναλαμβανόμενες τροποποιήσεις αρχείων. Όταν πρέπει να γίνουν αλλαγές σε μεγάλο αριθμό αρχείων, ο sed είναι πολύ βοηθητικός.


5.1.2. Εντολές του sed 

Το πρόγραμμα sed μπορεί να εκτελέσει αντικαταστάσει, τροποποιήσεις και διαγραφές προτύπων κειμένου με τη χρήση κανονικών εκφράσεων, όπως στην εντολή grep; δείτε Ενότητα 4.2.

Οι εντολές είαι παρόμοιες με αυτές του συντάκτη vi:

Πίνακας 5-1. Εντολές sed 

Εντολή

Αποτέλεσμα

a\

Προσθήκη κειμένου μετά τη τρέχουσα γραμμή.

c\

Αντικατάσταση κειμένου τρέχουσας γραμμής με νέο κείμενο.

d

Διαγραφή κειμένου.

i\

Εισαγωγή κειμένου πριν τη τρέχουσα γραμμή.

p

Εμφάνιση κειμένου.

r

Ανάγνωση από αρχείο.

s

Εύρεση και αντικατάσταση κειμένου.

w

Εγγραφή σε αρχείο.

Εκτός από τις παραπάνω εντολές, υπάρχουν αρκετές επιλογές του sed. Μια σύνοψη φαίνεται παρακάτω:

Πίανκας 5-2. Επιλογές sed

Εντολή

Αποτέλεσμα

-e SCRIPT

Προσθέτει τις εντολές στο SCRIPT στο σύνολο των εντολών που θα εκτελεστούν κατά την επεξεργασία της εισόδου.

-f

Προσθέτει τις εντολές που περιλαμβάνονται στο αρχείο SCRIPT-FILE στο σύνολο των εντολών που θα εκτελεστούν κατά την επεξεργασία της εισόδου.

-n

Σιωπηλή κατάσταση.

-V

Εμφάνιση πληροφοριών έκδοσης και έξοδος.

Οι σελίδες πληροφοριών του sed περιέχουν περισσότερα στιοχεία, εδώ απλά παραθέτουμε τις συνηθέστερες εντολές και επιλογές. 


5.2. Διαλογική σύνταξη

5.2.1. Εμφάνιση γραμμών που περιέχουν ένα πρότυπο

Αυτό είναι κάτι που μπορείτε να κάνετε με τη grep, βέβαια, αλλά δεν μπορείτε να εκτελέσετε "εύρεση και αντκατάσταση". Αυτό σαν αρχή.

Αυτό είναι το αρχείο μας:

 
sandy ~> cat -n example
&nbs