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

Η ταυτόχρονη εκτέλεση πολλών εργασιών, η ανακατεύθυνση, η διασωλήνωση, ο χρονοπρογραμματισμός με το crontab και τα aliases, αποτελούν μερικά μόνο από τα πανίσχυρα εργαλεία που προσφέρει το κέλυφος. Μεταξύ αυτών, εκείνα που θα φανούν περισσότερο χρήσιμα (και μερικές φορά εντυπωσιακά) είναι η διασωλήνωση και τα συνώνυμα. Πράγματι, η αποστολή αυτών των δύο είναι αφηρημένη και δεν περιορίζεται σε ένα συγκεκριμένο πεδίο εφαρμογών. Με τη βοήθειά τους μπορούμε να επινοούμε λύσεις σε αρκετά σύνθετα προβλήματα και μάλιστα με άνεση και ταχύτητα. Κάτι αντίστοιχο ισχύει και με τα λεγόμενα σενάρια κελύφους (shell scripts). Μπορείτε να τα φαντάζεστε σαν τα batch files (αρχεία BAT) των Windows, μόνο που στην πραγματικότητα τα shell scripts είναι κλάσεις ανώτερα. Τα σενάρια κελύφους δεν περιορίζονται σε μια απλή παράθεση εντολών. Τις περισσότερες φορές περιέχουν κατάλληλες προγραμματιστικές δομές, οι οποίες προσδίδουν εσωτερική λογική αλλά και το στοιχείο της αλληλεπίδρασης με το περιβάλλον. Με άλλα λόγια, τα σενάρια μπορούν να περιλαμβάνουν επαναληπτικές δομές ή δομές ελέγχου και διακλάδωσης, ώστε να προσαρμόζουν τη συμπεριφορά τους ανάλογα με τις παραμέτρους που έχουν δεχτεί κατά την εκτέλεση. Σε αυτό το άρθρο, βέβαια, δεν θα κάνουμε μαθήματα προγραμματισμού. Αντίθετα, θα θεωρήσουμε ότι έχετε μερικές βασικές γνώσεις και θα προχωρήσουμε σε μία γνωριμία με τη γλώσσα του BASH, μέσα από μια σειρά συγκεκριμένων παραδειγμάτων. Πριν ξεκινήσουμε, όμως, πρέπει να αναφέρουμε μερικές λεπτομέρειες. Κατ’ αρχάς, όλα τα σκριπτάκια που θα δούμε (όπως κι εκείνα που ελπίζουμε ότι θα αρχίσετε να δημιουργείτε μόνοι σας) πρέπει να γράφονται σε κάποιον διορθωτή απλού κειμένου. Για παράδειγμα, στην κονσόλα μπορούμε να χρησιμοποιούμε το nano, ενώ αν βρισκόμαστε σε παραθυρικό περιβάλλον μπορούμε να χρησιμοποιούμε προγράμματα όπως τα Gedit, Kate κ.ά. Αφού γράψουμε κι αποθηκεύσουμε το script μας, για να μπορέσουμε να το εκτελέσουμε πρέπει προηγουμένως να τροποποιήσουμε κατάλληλα τα δικαιώματα πρόσβασης σε αυτό ώστε να γίνει εκτελέσιμο. Κάτι τέτοιο γίνεται πανεύκολα με το προγραμματάκι chmod. Για παράδειγμα, αν έχουμε φτιάξει ένα script με το όνομα my_super_script, το κάνουμε εκτελέσιμο έτσι:

chmod 744 my_super_script

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

./my_super_script

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

~/scripts/my_super_script

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

Έξυπνη διαγραφή (πλήρες script)

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

./delete.sh όνομα_κάποιου_αρχείου

Κατ’ αυτόν τον τρόπο, το αρχείο που προσδιορίζετε μεταφέρεται σε έναν κρυφό κατάλογο στο home directory του χρήστη, ονόματι .my-trash. Σημειώστε ότι αν ο συγκεκριμένος κατάλογος δεν υπάρχει, το σκριπτάκι μας θα φροντίσει να τον δημιουργήσει. Στην περίπτωση που αργότερα μετανιώσετε για τη διαγραφή του αρχείου, αρκεί να μεταβείτε στον κατάλογο .my_trash και να ρίξετε μια ματιά τριγύρω. Με αυτό το σενάριο θα μπορούσαμε να αντικαταστήσουμε το πρόγραμμα rm, τουλάχιστον όταν επιτελούμε κρίσιμες εργασίες και χειριζόμαστε πολύτιμα αρχεία. Κάτι τέτοιο θα μπορούσε να γίνει με το κατάλληλο alias. Για παράδειγμα, αν έχουμε αποθηκεύσει το delete.sh στον κατάλογο ~/my_scripts, θα μπορούσαμε να ορίσουμε το ακόλουθο alias…

alias del='~/my_scripts/delete.sh'

…ή και το ακόμα πιο δραστικό…

alias rm='~/my_scripts/delete.sh'

Αυτόματο άδειασμα του κάδου (πλήρες script)

Το σενάριο delete.sh μπορεί να μας σώσει από μία καταστροφική απροσεξία. Ωστόσο, η συνεχής του χρήση μάλλον θα αυξήσει γρήγορα και υπερβολικά το μέγεθος του καταλόγου ~/.my-trash. Κάπως έτσι, προκύπτει η ανάγκη ενός μηχανισμού ο οποίος θα φροντίζει να αδειάζει τον εν λόγω κατάλογο. Το σενάριο που μπορεί να κάνει αυτή τη δουλειά είναι το cron_del.sh και, όπως δηλώνει το όνομά του, προορίζεται για αυτόματη εκτέλεση με τη βοήθεια του crontab. Η αποστολή του είναι να διαγράφει οτιδήποτε μεταφέρθηκε στον κατάλογο .my-trash την προηγούμενη εβδομάδα. Αν υποθέσουμε ότι το έχουμε αποθηκεύσει στον κατάλογο /home/pvar/my_scripts, θα πρέπει να προσθέσουμε στο crontab μία γραμμή σαν την ακόλουθη:

0 10 * * * /home/pvar/my_scripts/cron_del.sh

Με αυτόν τον τρόπο το cron_del.sh θα εκτελείται κάθε Κυριακή, στις δέκα το πρωί.

Έξυπνη αποσυμπίεση (πλήρες script)

Για τον κόσμο του Unix διατίθεται μια πληθώρα εργαλείων συμπίεσης ή πακεταρίσματος αρχείων. Τα δημοφιλέστερα απ’ όλα είναι τα εξής τρία: bzip2, gzip και tar. Υπάρχει όμως πραγματικός λόγος να θυμόμαστε απ’ έξω τη σύνταξη τριών διαφορετικών εργαλείων; Η αλήθεια είναι ότι υπάρχει, αλλά όταν θέλουμε να αποσυμπιέσουμε κάτι στα γρήγορα δεν χρειάζεται να μπλέκουμε με το συντακτικό αυτών των εργαλείων. Γι’ αυτό το λόγο δημιουργήσαμε το σενάριο unpack.sh. Όταν το εκτελούμε, ελέγχει αν το αρχείο που δώσαμε ως παράμετρο είναι συμπιεσμένο. Εφόσον είναι, ανιχνεύει τη μέθοδο συμπίεσης και προχωρά στην αποσυμπίεσή του, χρησιμοποιώντας το κατάλληλο εργαλείο. Έτσι, για να αποσυμπιέσουμε στα γρήγορα ένα πακέτο αρκεί να δώσουμε κάτι τέτοιο:

~/my_scripts/unpack.sh ονομα_συμπιεσμένου_αρχείου

Ώρα για λίγη μελέτη

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

#!/bin/bash

Αυτή η γραμμή δηλώνει το διερμηνευτή (interpreter) που θα αναλάβει την εκτέλεση του σεναρίου. Το κέλυφος BASH δεν είναι ο μοναδικός υποψήφιος interpreter. Για παράδειγμα, ένα σενάριο κελύφους θα μπορούσε να γραφεί σε Perl ή σε Python. Σε αυτές τις περιπτώσεις η πρώτη γραμμή θα ήταν κάπως έτσι…

#!/bin/perl

…ή κάπως έτσι:

#!/bin/python

Ας προχωρήσουμε τώρα λίγο παρακάτω, στο σενάριο delete.sh.

if [ -f "$filename" ]; then
    echo "The file exists. That's good!"
else
    echo "The file doesn't exist or isn't regular!"
    exit
fi

Όπως αναφέραμε προηγουμένως, η γλώσσα του BASH διαθέτει όλες τις παραδοσιακές δομές ελέγχου που προσφέρουν οι γλώσσες προγραμματισμού. Στο συγκεκριμένο απόκομμα βλέπουμε ένα παράδειγμα χρήσης της δομής ελέγχου if...then...else. Πρόκειται για την απλούστερη δομή ελέγχου και διακλάδωσης. Σε αυτό το κομμάτι, το script ελέγχει για την ύπαρξη του αρχείου που δώσαμε ως παράμετρο. Αν αποτύχει να εντοπίσει τον αρχείο, ενημερώνει το χρήστη και τερματίζει τη λειτουργία του. Διαφορετικά ενημερώνει και πάλι το χρήστη, αλλά συνεχίζει κανονικά την εκτέλεσή του αφού προηγουμένως τερματίσει τη δομή if...then...else. Ο τερματισμός αυτής της δομής σηματοδοτείται με το fi. Ας δούμε τώρα κι ένα απόσπασμα από το σενάριο unpack.sh:

case $filetype in
"bzip2compressed" )
    echo "The file is compressed with bzip2. Decompressing..."
    bzip2 -d $filename
;;

...

* ) 
    echo "The file is compressed (or packed) with an unknown tool"
    echo "or it is not compressed at all..."
    echo -n "Filetype: "`file $filename | awk '{ print $2 }'`
    echo " "`file $filename | awk '{ print $3 }'`
    ;;
esac

Η ομοιότητα με άλλες γλώσσες προγραμματισμού επεκτείνεται σε όλες τις παραδοσιακές δομές. Στο προηγούμενο απόσπασμα βλέπουμε ένα παράδειγμα της δομής πολλαπλού ελέγχου και διακλάδωσης, ονόματι case. Στη γλώσσα C η αντίστοιχη δομή ονομάζεται switch, ενώ στην BASIC αποκαλείται select case. Σε αυτή την περιοχή, το σκριπτάκι μας ελέγχει τον τύπο του αρχείου και προχωρά στην αποσυμπίεση με το κατάλληλο εργαλείο. Αν το αρχείο είναι συμπιεσμένο με άγνωστη μέθοδο, το script εμφανίζει τον τύπο του αρχείου κι ενημερώνει το χρήστη για την αποτυχία του. Εδώ αξίζει να σταθούμε για λίγο και να εξετάσουμε μια ενδιαφέρουσα λεπτομέρεια. Παρακάτω φαίνεται η γραμμή που τυπώνει τον τύπο του επιλεγμένου αρχείου:

filetype=`file $filename | awk '{ print $2$3}'`

Βλέπουμε μια ιδιαίτερα ενδιαφέρουσα δυνατότητα του BASH. Ο λόγος γίνεται για το λεγόμενο command substitution. Παρατηρείστε λίγο τον κώδικα. Το BASH θα εκτελέσει όλα όσα υπάρχουν ανάμεσα στους χαρακτήρες του απλού εισαγωγικού (back-tick). Στη συνέχεια, το αποτέλεσμα από αυτήν την εκτέλεση θα αποδοθεί ως τιμή στη μεταβλητή filetype. Ας δούμε τώρα τι γίνεται ανάμεσα στα back-ticks. Αρχικά εκτελείται το πρόγραμμα file, με παράμετρο το αρχείο που δώσαμε κατά την εκτέλεση του script. Το όνομα αυτού του αρχείου έχει αποδοθεί στη μεταβλητή filename. Το αποτέλεσμα αυτής της εκτέλεσης θα είναι η εμφάνιση μιας ολόκληρης πρότασης, η οποία θα περιγράφει τον τύπο του συγκεκριμένου αρχείου. Αυτή η πρόταση, με τη βοήθεια της διασωλήνωσης, θα σταλεί ως είσοδος στο πρόγραμμα awk. Με τη βοήθεια του τελευταίου, απομονώνονται και τυπώνονται η δεύτερη και η τρίτη λέξη. Οι συγκεκριμένες λέξεις γνωρίζουμε ότι αποτελούν τον τύπο του αρχείου και ακριβώς αυτές θα αποδοθούν τελικά στη μεταβλητή filetype.

Αυτόματη δημιουργία αναφοράς (πλήρες script)

Είτε έχουμε πέντε cloud servers που εξυπηρετούν πενήντα χιλιάδες πελάτες ο καθένας είτε έναν μικρό server στο σπίτι με μοναδικό πελάτη το PC του διπλανού δωματίου, είναι σίγουρο ότι θα θέλαμε πάντα να γνωρίζουμε την κατάσταση του εκάστοτε συστήματος. Για παράδειγμα, θα είχε ενδιαφέρον αν μπορούσαμε να βλέπουμε εύκολα τα στατιστικά από τη χρήση των αποθηκευτικών μέσων, το σύνολο του τάδε είδους συνδέσεων που δέχτηκε το μηχάνημα, τη θερμοκρασία των δίσκων και πάει λέγοντας. Στην πράξη, για να βρούμε αυτά τα στοιχεία πρέπει πρώτα να ψάξουμε σε ένα σωρό τοποθεσίες και, φυσικά, να έχουμε συνδεθεί στο μηχάνημα που εξετάζουμε. Δεν θα ήταν καλύτερα αν όλα τα στοιχεία συγκεντρώνονταν αυτόματα; Ε, λοιπόν, ένα μικρό script για το BASH θα μπορούσε πανεύκολα να πετύχει αυτό το στόχο. Στη συνέχεια θα μελετήσουμε μια απλοϊκή εκδοχή ενός τέτοιου script. Το σενάριό μας προβάλει τα διάφορα στοιχεία σε μια σελίδα HTML. Ας δούμε το εν λόγω script τμήμα προς τμήμα.

Σελίδα αναφοράς. Για τη δημιουργία της σελίδας HTML, το script πρέπει να τυπώνει όσες πληροφορίες συλλέγει ανάμεσα στα κατάλληλα HTML tags. Φυσικά, τα tags και οι πληροφορίες θα μπορούσαν να τυπώνονται με τη χρήση του προγράμματος echo. Ωστόσο, όταν θέλουμε να τυπώσουμε αρκετές γραμμές κειμένου χωρίς να ανησυχούμε για τους ειδικούς χαρακτήρες που ενδέχεται να περιέχουν, είναι καλύτερα να χρησιμοποιούμε το cat. Στις πρώτες γραμμές του script, φαίνεται ένα εξυπηρετικό κολπάκι:

#!/bin/bash

cat << REPORTSTART
<html>
<head><title>System Report</title></head>
<body bgcolor="#c0c0c0" text="#000000">
<p><hr size=4></hr></p>
<h1>System Report</h1>
<p><hr size=4></hr></p>
REPORTSTART

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

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

echo "<p><b>System name: </b>"
hostname
echo "</p>"

echo "<p><b>Kernel version: </b>"
uname --kernel-release
echo "</p>"

Προφανώς, το πρόγραμμα hostname τυπώνει το όνομα του μηχανήματος, ενώ το uname (με τις συγκεκριμένες παραμέτρους) εμφανίζει την έκδοση του πυρήνα που χρησιμοποιείται στο σύστημα. Σε παρόμοιες ενότητες θα μπορούσαμε να αξιοποιήσουμε πολλά ακόμα προγράμματα του κελύφους. Για παράδειγμα, θα μπορούσαμε να χρησιμοποιήσουμε το uptime, ώστε να εμφανίζεται κι ο συνολικός χρόνος λειτουργίας του συστήματος μετά την τελευταία εκκίνηση.

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

cat << HARDWAREINFO
<p><hr></hr></p>
<p><b>Hardware information: </b></p>
<dl><dd><small><pre>
HARDWAREINFO

echo -e "CPU model: \t \c"
grep 'model name' -m 1 /proc/cpuinfo | awk '{print $5" "$6" "$7" "$8}'

echo -e "Main memory: \t \c"
grep 'MemTotal' /proc/meminfo | awk '{print $2" "$3}'

echo -e "SWAP memory: \t \c"
grep 'SwapTotal' /proc/meminfo | awk '{print $2" "$3}'

echo "</pre></small></dd></dl>" 

Όπως και στο πρώτο τμήμα που εξετάσαμε, για την εκτύπωση αρκετών διαδοχικών γραμμών HTML χρησιμοποιείται το κολπάκι με το πρόγραμμα cat. Κατ’ αυτόν τον τρόπο, τυπώνεται μία επικεφαλίδα για την ενότητα (hardware information) ενώ ταυτόχρονα ξεκινά μια περιοχή (<dl><dd><small>...) στην οποία θα εμφανίζονται τα πάντα με μικρότερο μέγεθος και μετατοπισμένα κατά μία στήλη (ένα TAB) δεξιά. Αμέσως μετά, με τη βοήθεια του grep το σκριπτάκι φιλτράρει τις ζητούμενες πληροφορίες από τα αρχεία /proc/cpuinfo και /proc/meminfo. Σε αυτό το τμήμα, πέρα από τα δύο αρχεία του συστήματος ενδιαφέρον έχει και η χρήση του echo. Με την παράμετρο -e ενεργοποιούνται οι ειδικές αλληλουχίες χαρακτήρων (sequences) όπως είναι η \t και η \c. Η πρώτη επιβάλει την εκτύπωση ενός χαρακτήρα TAB και η δεύτερη αποτρέπει την εκτύπωση του χαρακτήρα ENTER. Έτσι, οι πληροφορίες που συλλέγει το grep σε κάθε περίπτωση προβάλλονται δίπλα από τα μηνύματα που εμφανίζονται με το echo κι όχι στην από κάτω γραμμή.

Περισσότερα στοιχεία

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

cat << DFINFO
<p><hr></hr></p>
<p><b>Mounted volumes: </b></p>
<dl><dd><small><pre>
DFINFO

df -hT
echo "</pre></small></dd></dl>"

Σε αυτή την περιοχή χρησιμοποιείται το εργαλείο df, για την προβολή όλων των προσαρτημένων κατατμήσεων. Η παράμετρος T επιβάλλει την προβολή του είδους κάθε filesystem, ενώ η παράμετρος h καθορίζει σαν μονάδες μέτρησης τα TiB, GiB, MiB και KiB (η αναφορά μας θέλουμε να είναι ευανάγνωστη).

cat << SYSCRON1
<p><hr></hr></p>
<p><b>Scheduled tasks: </b><tt>(system wide)</tt></p>
<dl><dd> <small><pre>
SYSCRON1

cat /etc/crontab
echo "</pre></small></dd></dl>"

Με τις παραπάνω γραμμές εμφανίζονται οι προγραμματισμένες εργασίες που εκτελεί ο cron deamon, για λογαριασμό ολόκληρου του συστήματος. Αυτό επιτυγχάνεται με την εκτύπωση των περιεχομένων του αρχείου /etc/crontab.

cat << SSHSTATS
<p><hr></hr></p>
<p><b>SSH statistics: </b></p>
<dl><dd><small><pre>
SSHSTATS

yesterday="`date -d yesterday +%d`"
thismonth="`date -d yesterday +%b`"

cat /var/log/messages | grep sshd | grep "$thismonth $yesterday" >> /tmp/.my_tmp
tmp1="`cat /tmp/.my_tmp | grep Accepted | wc -l`"
tmp2="`cat /tmp/.my_tmp | grep "Invalid user" | wc -l`"
tmp3="`cat /tmp/.my_tmp | grep "authentication failure" | wc -l`"

echo -e "Valid connections: \t $tmp1"
echo -e "invalid username: \t $tmp2"
echo -e "invalid password: \t $tmp3"

echo "</pre></small></dd></dl>"

Σε αυτή την περιοχή το σκριπτάκι αποκτά ιδιαίτερο ενδιαφέρον. Μετά την εκτύπωση των απαραίτητων γραμμών HTML, ορίζονται δύο μεταβλητές. Στη μία αποθηκεύεται η χθεσινή ημερομηνία και στην άλλη το όνομα του μήνα. Οι τιμές των δύο μεταβλητών χρησιμοποιούνται ως φίλτρο για το grep. Έτσι, καταφέρνουμε να απομονώσουμε όλα τα μηνύματα από το γενικό αρχείο καταγραφής του συστήματος, που τυπώθηκαν την προηγούμενη μέρα. Τα εν λόγω μηνύματα αποθηκεύονται προσωρινά στο αρχείο /tmp/.my_tmp. Στη συνέχεια, με τη βοήθεια του grep και του εργαλείου wc, μετράμε πόσες φορές εμφανίζονται ορισμένα μηνύματα του SSH daemon. Έτσι, το script υπολογίζει και προβάλλει το πλήθος των πετυχημένων συνδέσεων στο σύστημα, καθώς και το πλήθος των αποτυχημένων.

Τερματισμός

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

cat << REPORTEND 
<p><hr size=5></hr></p> 
</body> 
</html> 
REPORTEND

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

./make_report > ~/report_file.html

Πλέον, δεν έχουμε παρά να ανοίξουμε το αρχείο report_file.html με κάποιον web browser και να θαυμάσουμε τη σελίδα που δημιούργησε το σενάριό μας.

Πρόσθετες δυνατότητες

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

Αρχικά, θα πρέπει να εγκαταστήσουμε το εργαλείο hddtemp. Η εγκατάσταση ενός πακέτου πραγματοποιείται με διαφορετικό τρόπο από διανομή σε διανομή, αλλά είμαστε βέβαιοι ότι θα μάθετε εύκολα τι πρέπει να κάνετε με την δική σας. Στη συνέχεια οφείλουμε να προσθέσουμε ένα νέο cronjob, το οποίο θα εκτελείται με αυξημένα δικαιώματα. Η εργασία που θα προσθέσουμε θα εκτελείται ανά μία ώρα και θα αποθηκεύει σε ένα προσωρινό αρχείο την τρέχουσα θερμοκρασία κάποιου δίσκου. Όπως καταλαβαίνετε, η λειτουργία του hddtemp απαιτεί δικαιώματα root κι ακριβώς γι’ αυτό το αντίστοιχο cronjob πρέπει να ανήκει στο συγκεκριμένο χρήστη. Για να δημιουργήσουμε ένα cronjob για τον root στο Ubuntu ή στο openSUSE, αρκεί να δώσουμε κάτι τέτοιο:

sudo crontab -e

Εναλλακτικά, μπορούμε να αποσυνδεθούμε από το δικό μας λογαριασμό, να συνδεθούμε σε εκείνον του root (με sudo su, στο Ubuntu ή στο openSUSE) και να πληκτρολογήσουμε:

`crontab -e`

Τώρα, αν υποθέσουμε ότι θέλουμε να παρακολουθούμε τη θερμοκρασία του δίσκου /dev/sda, αρκεί να δημιουργήσουμε το ακόλουθο cronjob:

0 */1   * * * /usr/sbin/hddtemp -n /dev/sda >> /tmp/.my_disk

Έτσι, το σύστημα θα καταγράφει αυτόματα (ανά μία ώρα) τη θερμοκρασία του δίσκου sda στο αρχείο /tmp/.my_disk. Τώρα πρέπει να βρούμε έναν τρόπο για τον υπολογισμό της μέσης θερμοκρασίας. Το script που φαίνεται παρακάτω πετυχαίνει ακριβώς αυτό: Προσθέτει όλες τις τιμές της θερμοκρασίας που βρίσκει στο αρχείο /tmp/.my_disk και στη συνέχεια διαιρεί το άθροισμα με το πλήθος των τιμών. Στο τέλος τυπώνεται το μέγεθος που προκύπτει (ο μέσος όρος) και το αρχείο με τις παλιές μετρήσεις θερμοκρασίας διαγράφεται:

#!/bin/bash
for i in `cat /tmp/.my_disk`; do 
    tbd=$(($tbd + $i))
    tmp=$(($tmp + 1))
done

tbd=$(($tbd / $tmp))
echo $tbd

rm /tmp/.my_disk
exit

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

Επίλογος (λέμε τώρα)

Κάπου εδώ αναγκαζόμαστε και σταματάμε –έστω και προσωρινά– την περιήγησή μας στον κόσμο της γραμμής εντολών και του BASH. Θέλουμε να πιστεύουμε ότι μέσα από αυτή τη μίνι σειρά άρθρων φάνηκε καλύτερα ο αληθινός χαρακτήρας του Linux (καθώς και άλλων UNIX-like συστημάτων). Ελπίζουμε πως όλα όσα συζητήσαμε θα σας κάνουν να εκτιμήσετε περισσότερο τις δυνατότητές του. Στοιχηματίζουμε ότι αρκετοί από εσάς θα το ψάξετε περισσότερο και θα φτάσετε πολύ πιο μακριά. Εδώ που τα λέμε, είμαστε βέβαιοι οπότε δεν χρειάζεται καν να στοιχηματίσουμε.

Άρθρα της σειράς

Μέρος 14: Αρχική προσέγγιση

Μέρος 24: Πρώτη επίθεση

Μέρος 34: Πλήρης έλεγχος

Μέρος 44: Προγραμματισμός στο BASH

~Spir@l Evolut10n