Loading…

Η εργαλειοθήκη του Unix – Fosscomm 2013

Στο πλαίσιο του συνεδρίου Fosscomm ο Διομήδης Σπινέλλης οργάνωσε εργαστήρι με τίτλο “Η εργαλειοθήκη του Unix: ισχυρά εργαλεία για δυνατούς προγραμματιστές”.

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

Δούλευοντας με τα εργαλεία Unix

Τα απλά αρχεία κειμένου χωρισμένα σε γραμμές είναι ο ελάχιστος κοινός παρονομαστής για πολλά από τα δεδομένα που περνούν από τα χέρια μας. Τα αρχεία αυτά μπορούν να χρησιμοποιηθούν για να αναπαραστήσουν τον πηγαίο κώδικα ενός προγράμματος, τα δεδομένα καταγραφής ενός διαδικτυακού εξυπηρετητή, την ιστορία ενός συστήματος ελέγχου εκδόσεων, λίστες αρχείων, πίνακες συμβόλων, περιεχόμενα αρχειοθηκών, μηνύματα λάθους, δεδομένα αξιολόγησης απόδοσης, κ.λπ. Για πολλές συνηθισμένες καθημερινές εργασίες, πιθανώς να μπούμε στον πειρασμό να επεξεργαστούμε τα δεδομένα με μία ισχυρή σεναριογλώσσα, όπως Perl, Python, ή Ruby. Ωστόσο, για να γίνει αυτό συνήθως χρειάζεται να γράψουμε ένα μικρό, αυτόνομο πρόγραμμα και να το αποθηκεύσουμε σε ένα αρχείο. Σε αυτό το σημείο έχουμε συχνά χάσει το ενδιαφέρον για την εργασία, και καταλήγουμε να κάνουμε τη δουλειά χειροκίνητα, ή και καθόλου. Συχνά, μια πιο αποτελεσματική προσέγγιση είναι να συνδυάσουμε προγράμματα της εργαλειοθήκης Unix σε μια σύντομη και εύκολη σωλήνωση εντολών που μπορεί να εκτελεστεί από τη γραμμή εντολών. Με τις σύγχρονες δυνατότητες επεξεργασίας της γραμμής εντολών μπορούμε να αναπτύξουμε την εντολή μας κομμάτι-κομμάτι, μέχρι να πάρει ακριβώς τη μορφή που θέλουμε. Σήμερα, η πρότυπη εργαλειοθήκη Unix είναι διαθέσιμη σε πολλά διαφορετικά συστήματα, όπως GNU/Linux, Mac OS X και Microsoft Windows. Συνεπώς δεν υπάρχει κανένας λόγος να μην προσθέσετε την προσέγγιση αυτή στο οπλοστάσιό σας.

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

Συγκεντρώνοντας τα δεδομένα

Τις περισσότερες φορές τα δεδομένα σας θα είναι κείμενο, το οποίο μπορείτε άμεσα να τροφοδοτήσετε ως είσοδο σε ένα εργαλείο. Εάν αυτό δεν είναι δυνατό, χρειάζεται να προσαρμόσετε τα δεδομένα σας. Αν τα δεδομένα σας βρίσκονται σε μορφή δυαδικών αρχείων, θα πρέπει να χρησιμοποιήσετε μια εντολή όπως nm (Unix), dumpbin (Windows), ή javap (Java) για να τα διαχειριστείτε. Αν εργάζεστε με αρχεία ομαδοποιημένα σε μια αρχειοθήκη, τότε μια εντολή όπως tar, jar, ή ar θα σας αποδώσει τα περιεχόμενα του αρχείου. Εάν τα δεδομένα σας προέρχονται από μια (ενδεχομένως μεγάλη) συλλογή αρχείων, η εντολή find μπορεί να εντοπίσει εκείνα που σας ενδιαφέρουν. Από την άλλη πλευρά, για να πάρετε τα δεδομένα σας μέσω διαδικτύου, χρησιμοποιήστε το πρόγραμμα wget ή curl. Μπορείτε επίσης να χρησιμοποιήσετε το dd (και το ειδικό αρχείο /dev/zero), το yes ή το jot για να παράγετε τεχνητά δεδομένα, τα οποία είναι χρήσιμα για την εκτέλεση μιας γρήγορης δοκιμής συγκριτικής αξιολόγησης. Τέλος, αν θέλετε να επεξεργαστείτε τον κατάλογο λαθών ενός μεταγλωττιστή, θα πρέπει να ανακατευθύνετε τον τυπικό αγωγό σφάλματός του στον τυπικό αγωγό εξόδου του. Η εντολή 2>&1 κάνει ακριβώς αυτό.

Υπάρχουν πολλές άλλες περιπτώσεις που δεν έχουμε καλύψει εδώ: σχεσιακές βάσεις δεδομένων, συστήματα ελέγχου εκδόσεων, πελάτες ηλεκτρονικού ταχυδρομείου, εφαρμογές γραφείου, και ούτω καθεξής. Πάντα να έχετε υπόψη ότι είναι απίθανο να είστε οι πρώτοι που χρειάζεται να μετατρέψουν τα δεδομένα της εφαρμογής σε μορφή κειμένου. Ως εκ τούτου κάποιος έχει πιθανότατα ήδη αναπτύξει ένα εργαλείο για αυτή τη δουλειά. Για παράδειγμα, η εργαλειοθήκη Outwit (http://www.spinellis.gr/sw/outwit) μπορεί να μετατρέψει σε μια ροή δεδομένων κειμένου αρχεία που προέρχονται από το «πρόχειρο» των Windows, μια πηγή ODBC, το αρχείο καταγραφής συμβάντων, ή το μητρώο των Windows.

Επιλογή

Δεδομένης της γενικευμένης χρήσης των δεδομένων που βρίσκονται σε μορφή κειμένου, στις περισσότερες περιπτώσεις θα έχετε στα χέρια σας περισσότερα δεδομένα από όσα χρειάζεστε. Πιθανώς να θέλετε να επεξεργαστείτε μόνο ορισμένα τμήματα της κάθε γραμμής, ή μόνο ένα υποσύνολο των γραμμών. Για να επιλέξετε μια συγκεκριμένη στήλη από μια γραμμή που αποτελείται από στοιχεία που διαχωρίζονται από κενό ή άλλο στοιχείο οριοθέτησης, χρησιμοποιήστε την εντολή awk με μια μονή εντολή print $n. Αν τα πεδία σας είναι σταθερού πλάτους, τότε μπορείτε να τα διαχωρίσετε με την εντολή cut. Και, αν οι γραμμές σας δεν είναι χωρισμένες τακτικά σε πεδία, μπορείτε συχνά να γράψετε μια κανονική έκφραση ως εντολή αντικατάστασης του διορθωτή ροής sed ώστε να απομονώσετε το στοιχείο που θέλετε.

Η κινητήριος δύναμη για την απόκτηση ενός υποσυνόλου των σειρών είναι το εργαλείο grep. Καθορίστε μια κανονική έκφραση για να πάρετε μόνο τις γραμμές που ταιριάζουν σε αυτή, και προσθέστε το όρισμα -v για να φιλτράρετε τις γραμμές που δεν θέλετε να επεξεργαστείτε. Χρησιμοποιήστε την εντολή fgrep με το όρισμα -f, εάν τα στοιχεία που ψάχνετε είναι σταθερά και αποθηκευμένα σε αρχείο (που ίσως παράχθηκε σε προηγούμενο στάδιο επεξεργασίας). Αν τα κριτήρια επιλογής σας είναι πιο περίπλοκα, μπορείτε συνήθως να τα εκφράσετε με μια έκφραση επιλογής της εντολής awk. Πολλές φορές θα πιάσετε τον εαυτό σας να συνδυάζει μια σειρά από αυτές τις προσεγγίσεις ώστε να πετύχετε το επιθυμητό αποτέλεσμα. Για παράδειγμα, μπορεί να χρησιμοποιήσετε την εντολή grep για να πάρετε τις γραμμές που σας ενδιαφέρουν, grep -v για να φιλτράρετε κάποιο θόρυβο από το δείγμα σας, και, τέλος, το awk ώστε να επιλέξετε ένα συγκεκριμένο πεδίο από κάθε γραμμή.

Επεξεργασία

Θα διαπιστώσετε ότι η επεξεργασία δεδομένων συχνά περιλαμβάνει την ταξινόμηση των γραμμών χρησιμοποιώντας ένα συγκεκριμένο πεδίο. Η εντολή sort υποστηρίζει δεκάδες επιλογές για τον καθορισμό των κριτηρίων ταξινόμησης, τον τύπο τους και τη σειρά εξόδου. Αφού ταξινομήσετε τα αποτελέσματά σας τότε συχνά θέλετε να απαριθμήσετε τις εμφανίσεις κάθε στοιχείου. Η εντολή uniq με την επιλογή -c, κάνει ακριβώς αυτό. Συχνά θα επεξεργαστείτε εκ νέου το αποτέλεσμα εκτελώντας άλλη μία ταξινόμηση, αυτή τη φορά με την επιλογή -n που καθορίζει αριθμητική προτεραιότητα, για να μάθετε ποια στοιχεία εμφανίζονται πιο συχνά. Σε άλλες περιπτώσεις ίσως να θέλετε να συγκρίνετε τα αποτελέσματα μεταξύ διαφορετικών εκτελέσεων. Μπορείτε να χρησιμοποιήσετε την εντολή diff αν οι δύο εκτελέσεις παράγουν αποτελέσματα τα οποία θα πρέπει να είναι όμοια (ίσως τα αποτελέσματα μιας δοκιμής παλινδρόμησης), ή την εντολή comm αν θέλετε να συγκρίνετε δύο ταξινομημένες λίστες. Τέλος, θα χειριστείτε πιο σύνθετες εργασίες χρησιμοποιώντας, και πάλι την εντολή awk.

Συνοψίζοντας

Σε πολλές περιπτώσεις, τα επεξεργασμένα δεδομένα είναι πολύ ογκώδη για να είναι χρήσιμα. Για παράδειγμα, ίσως να μην σας νοιάζει ποια σύμβολα ορίζονται με λανθασμένη ορατότητα στο πρόγραμμα μας, αλλά μπορεί να θέλετε να ξέρετε πόσα υπάρχουν. Παραδόξως, πολλά προβλήματα αφορούν την απλή καταμέτρηση του αποτελέσματος του σταδίου επεξεργασίας χρησιμοποιώντας την απλούστατη εντολή wc (word count) και το όρισμα -l. Αν θέλετε να μάθετε τα κορυφαία ή τελευταία 10 στοιχεία της λίστας αποτελεσμάτων σας, τότε μπορείτε να τροφοδοτήσετε τη λίστα σας στο εργαλείο head ή στο tail. Για να μορφοποιήσετε μια μεγάλη λίστα λέξεων σε ένα πιο διαχειρίσιμο σύνολο που μπορείτε στη συνέχεια να επικολλήσετε σε ένα πρόγραμμα, χρησιμοποιήστε το fmt (ίσως εκτελώντας το μετά από μια εντολή αντικατάστασης του sed που προσθέτει ένα κόμμα μετά από κάθε στοιχείο). Επίσης, για σκοπούς εντοπισμού σφαλμάτων ίσως σωληνώσετε αρχικά το αποτέλεσμα των ενδιάμεσων σταδίων στο πρόγραμμα more ή στο less, για να το εξετάσετε λεπτομερώς. Ως συνήθως, χρησιμοποιείστε το awk όταν αυτές οι προσεγγίσεις δεν σας ταιριάζουν. Μία τυπική εργασία για το πρόγραμμα awk περιλαμβάνει την εύρεση του συνολικού αθροίσματος ενός συγκεκριμένου πεδίου χρησιμοποιώντας μια εντολή όπως η sum += $3.

Σύνδεση

Όλα τα υπέροχα στοιχεία που περιγράψαμε είναι άχρηστα χωρίς κάποιο τρόπο να συνδυαστούν μαζί. Για το σκοπό αυτό θα χρησιμοποιήσετε τις δυνατότητες του φλοιού Bourne. Πρώτα απ’ όλα έρχεται η σωλήνωση (|), η οποία σας επιτρέπει να στείλετε το αποτέλεσμα ενός σταδίου επεξεργασίας ως είσοδο στο επόμενο στάδιο. Σε άλλες περιπτώσεις ίσως να θέλετε να εκτελέσετε την ίδια εντολή με πολλά διαφορετικά κριτήρια. Γι’ αυτό θα τροφοδοτήσετε τα ορίσματα ως είσοδο στο εργαλείο xargs. Ένα τυπικό μοτίβο περιλαμβάνει τη λήψη μιας λίστας αρχείων χρησιμοποιώντας την εντολή find, και την επεξεργασία τους μέσω xargs. Αυτό το μοτίβο είναι τόσο κοινό ώστε προκειμένου να χειρίζονται αρχεία με ενσωματωμένα διαστήματα, και οι δύο εντολές υποστηρίζουν την επιλογή (-print0 και -0) ώστε να τερματίζουν τα δεδομένα τους με έναν χαρακτήρα null, αντί για ένα διάστημα. Εάν η επεξεργασία που θέλετε να κάνετε είναι πιο περίπλοκη, μπορείτε πάντα να σωληνώσετε τα κριτήρια σε ένα βρόχο επανάληψης while read (ο φλοιός Bourne σας επιτρέπει να σωληνώσετε δεδομένα προς και από όλες τις δομές ελέγχου.) Αν όλα τα άλλα αποτύχουν, μη διστάσετε να χρησιμοποιήσετε μερικά ενδιάμεσα αρχεία ή το πρόγραμμα sgsh για να χειριστείτε τα δεδομένα σας.

Ολοκληρωμένο παράδειγμα

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

find src -name ‘*.java’ -print |

xargs fgrep -c .substring |

sort -t: -rn -k2 |

head -10

Η ακολουθία σωλήνωσης θα χρησιμοποιήσει πρώτα το εργαλείο find για να εντοπίσει όλα τα αρχεία Java, και θα εφαρμόσει το εργαλείο fgrep σε αυτά, μετρώντας (-c) τις εμφανίσεις της μεθόδου .substring. Στη συνέχεια, το εργαλείο sort θα διατάξει τα αποτελέσματα σε αντίστροφη αριθμητική σειρά (-rn), σύμφωνα με το δεύτερο πεδίο (-k2) χρησιμοποιώντας το σύμβολο : ως διαχωριστικό (-t:), και το εργαλείο head θα εκτυπώσει την κορυφαία δεκάδα.

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

 

Αφήστε μια απάντηση