Monday 14 January 2008

Linux Terminal - Μάθημα 6ο - Η πραγματική δύναμη της γραμμής εντολών

Εδω θα δουμε καποια προχωρημενα στοιχεία της γραμμης εντολων, που της δινουν απιστευτη δυναμη και ευελιξια.

Χρησιμοποιώντας περισσότερες από μια εντολές στην ίδια γραμμή εντολών

Μπορείτε να συνδυάσετε περισσότερες από μία εντολές στην ίδια κονσόλα. Αυτό επιτυγχάνετε με την χρήση του ; ανάμεσα στις εντολές.
Πχ $ cd /tmp;pwd;ls -l
Έτσι η παραπάνω εντολή θα αλλάξει τον κατάλογο στον /tmp Θα εμφανίσει σε ποιον κατάλογο εργαζόσαστε, και θα εμφανίσει και τα περιεχόμενα του.
Ας υποθέσουμε τώρα οτί θέλετε να εκτελέσετε την παραπάνω διαδικασία χωρις ομώς να αλλάξει ο τρέχων υποκατάλογος, επιπλέον θέλέτε να το κάνετε με την ίδια ακριβώς ακολουθία εντολών. Αυτό είναι εφικτό περικλείωντας τις εντολές σε (). Αυτό δημιουργεί ένα νέο κέλυφος, στο οποίο εκτέλουνται οι εντολές χωρίς να αλλοιωθεί το τρέχων περιβάλλον. Έτσι δίνωντας: $ (cd /tmp;pwd;ls -l)
Θα δημιουργηθεί ένα νέο περιβάλλον εκτέλεσης εντολών, σε αύτο το περιβάλλον θα εκτελεστουν οι εντολές και έπειτα θα επιστρέψουμε στο αρχικό χωρίς να έχει αλλάξει τίποτα!

Ανακατεύθυνση (redirection)

Μεγάλο μέρος της χρησιμότητας της κονσόλας εγκειταί στην δυνατότητα να ανακατευθήνουμε την είσοδο και την έξοδο των εντολών από και προς τα αρχεία. Τα περισσότερα προγράμματα του κέλυφους έχουν σχεδιαστεί ώστε να διαχείριζονται τα δεδομένα χρησιμοποιώντας ρευμάτα (streams). Ένα ρεύμα δεν είναι τίποτα άλλο πάρα δεδόμενα που κατευθύνονται προς μια είσοδο ή εξοδο. Έτσι συνήθως το ρευμά εισόδου μιας εντολής προέρχεται συνήθως από το πληκτρολόγιο, ενώ το ρευμά εξόδου από την οθόνη του τερματικού. Στο Linux τα προγράμματα επικαοινωνούν με τον εξώ κόσμο με τη βοήθεια τριών ρευμάτων: STDOUT(εξόδου),STDIN(εισόδου),STDERR(εξόδου λαθών). Τα ρευμάτα αυτά μπορουν να συνδεθούν μεταξύ τους με δίαφορετικους τρόπους διαμέσου του κέλυφους. Δηλάδη μπορεί να πάρουμε δεδομένα από ένα αρχείο να τα επεξεργαστούμε και να στείλουμε την εξόδο του αποτελέσματος σε κάποιο άλλο αρχείο. Αυτό ονομάζεται ανακατεύθυνση.

STDOUT

Τα περισσότερα προγράμματα που χρησιμοποιούμε στέλνουν τα αποτελέσματα τους στο προεπιλεγμένο ρεύμα έξοδου που είναι η οθόνη. Παρολαύτα μπορούμε εμείς να προσδιορίσουμε που ακριβώς θα κατευθυνθούν τα δέδομενα εξόδου. Για να το πετύχουμε αυτό χρησιμοποιούμε το σύμβολο > μετά την εντολή και στη συνέχεια το όνομα του αρχείου που θέλουμε να στείλουμε τα δεδομένα.
Για παράδειγμα η εντολή: $ ls -l > /home/user/catalog.ls αντί να τυπώσει την λίστα με τα περιέχομενα του κατάλογου στην οθόνη τα γράφει στο αρχείο catalog.ls. Εκτελώντας αυτήν την εντολή δεν θα εμφανιστεί τίποτα στην οθόνη, για να επαληθευσούμε οτι η έξοδος της εντολής στάλθηκε στο αρχείο που προσδίορισαμε μπορούμε να εκτέλεσουμε την εντολή:
$ cat /home/user/catalog.ls η οποία θα μας τυπώσει τα περιεχόμενα του αρχέιου στο προεπιλεγμένο ρεύμα εξόδου. Όπως είδαμε παραπάνω μπορούμε να τρέξουμε παραπάνω από μία εντολές στην ίδια γραμμή εντολών. Μπορούμε να ανακατευθύνουμε την έξοδο των πολλαπλών αυτών εντολών σε ένα αρχείο, αρκει βέβαια να περικλείσουμε τις εντολές προς ανακατευθύνση σε παρενθέσεις. Έτσι η εντολή: $ cd /home/user;(pwd;ls -l) > catalog.txt αλλάζει τον τρέχων κατάλογο σε /home/user και ανακατευθύνει την έξοδο των εντολών pwd και ls -l στο αρχέιο catalog.txt.
Ενώ θα περίμενε κανείς οτί όλες οι εντολές που χωρίζουμε με ; στέλνονται στ ρεύμα εξόδου, στην πραγματικότητα στέλνεται μόνο η τελευταία.
Έτσι μια εντολή της μορφής: $ ls -l;pwd > file θα ανακατευθύνει στο αρχείο file μόνο την έξοδο της εντολής pwd και οχι της ls-l.
Παρατήρηση: Καθέ φορά που ανακατευθύνουμε το ρεύμα εξόδου μια εντολής σε ένα αρχείο το αρχείο αυτο σβήνεται και πάνω του γράφονται τα νέα δεδομένα. Αν θέλουμε σε ένα παλίο αρχείο να προσαρτήσουμε δεδομένα, το πετυχαίνουμε με την χρήση του συμβόλου >> αντι για >.

STDERR

Το προεπιλεγμένο ρεύμα εξόδου λαθών είναι η οθόνη. Αν θελούμε για κάποιο λόγο να στείλουμε τα μυνήματα λάθους μιας εντολής σε κάποιο αρχείο θα πρέπει να το προσδίορισουμε χηρσιμοποιώντας το σύμβολο ανακατευθύνσης 2>. Τα ρεύματα έχουν έναν αριθμό που υποδηλώνει για ποιο ρεύμα πρόκειται. Έτσι το ρευμά εξόδου είναι το 0, το ρεύμα εισόδου το 1, και το ρεύμα εξόδου λαθών το 2.
Έτσι εκτελώντας πχ την εντολή: $ ls -R / > list.txt 2> errors θα μας τυπώσει τα αποτέλεσματα της εντολής ls -R / στο αρχείο list.txt, ενώ όλα τα μυνήματα λάθους θα τυπώθουν στο αρχείο errors.

STDIN

Είναι εφικτό να ανακατευθύνουμε το ρεύμα εισόδου, οπώς ακριβώς και τα δύο προηγούμενα. Για να καταλάβουμε την χρησιμότητα αυτής της διαδικασίας ας αναφερθούμε σε ένα παράδειγμα. Ας υποθέσουμε, οτι κάποιος εργάζεται σε μια εφημερίδα, και βασίκη εργασία του είναι να προετοιμάζει τις αγγέλιες για την εκτύπωση στην εφημερίδα. Πρώτα λοίπον για κάθε αγγελία ανοίγει το αρχείο /worker/aggelia.txt, αφαιρεί τις 4 πρώτες γραμμές που περιέχουν στοιχεία που αφορούν την εφημερίδα και όχι τους αναγνώστες, σώνει το κείμενο και βγαίνει στην γραμμή εντολών, οπου και γράφει το αρχείο στον φάκελο /boss/ ως /boss/aggelia.ready. Ας αυτοματοποιήσουμε την διαδικασία αυτή χρησιμοποιώντας τον vi και την ανακατευθύνση. Πρώτα δημιουργούμε ένα αρχείο με τίτλο i_am.smart με τα εξής περιεχόμενα :

4dd
:w/boss/aggelia.ready
:q!
Αφού δημιουργήσουμε το αρχείο τρέχουμε την εντόλη: $(vi /worker/aggelia.txt <> error.txt . Ελέγχόντας το αρχείο /boss/aggelia.ready βλέπουμε οτι η εργασία ολοκληρώθηκε με την χρήση της ανακατευθύνσης του ρευμάτος εισόδου.

Διασωλήνωση (pipes)

Το κέλυφος εντολών μας δίνει την δυνατότητα να χρησιμοποιήσουμε την έξοδο ενός προγράμματος ως είσοδο ενός άλλου. Αυτό το πετύχαίνουμε με την χρήση της διασωλήνωσης (pipe). Παραδείγματος χάριν είδαμε οτι η εντολή ls τυπώνει τα περιεχόμενα ενός καταλόγου, ενώ η head τις Ν πρώτες γραμμές ενός κειμένου. Αν θέλαμε λοιπόν να δούμε τις 4 πρώτες γραμμές του καταλόγου αρκει να τρέξουμε την εντολή: $ ls -l|head -n 4. Έτσι η head θα πάρει την εισόδο των δεδομένων της από την εντολή ls -l, και αφού τα επεξεργαστέι θα τυπώσει τις 4 πρώτες γραμμές.


Παραδέιγματα:

$ cat /etc/passwd|less (τυπώνει τα περιεχόμενα του /etc/passwd μια οθόνη τη φορά)

$ (who|head -n 5) > filename.txt (στέλνει στο filename.txt τα ονόματα των 5 πρώτων που είναι logged στο ίδιο μηχάνημα)

$ vi filename.txt < (cat /etc/passwd|grep "0") (στέλνει στο αρχείο filename.txt τις γραμμές του αρχείου /etc/passwd
με uid 0)

Συνήθεις εκφράσεις (Regular Expressions)

Μάλλον το συνήθεις εκφράσεις δεν ανταποκρίνεται και πάρα πολύ καλά στο όρο, έτσι θα αναφέρομαι με τον αγγλικό, regular expression, και για χαριν συντομίας θα χρησιμοποιώ τον όρο regex όταν αναφέρομαι στις συνήθεις εκφράσεις. Regexs είναι ο καθορισμός ειδικής ακολουθίας χαρακτήρων μπαλαντέρ (wildcards) μαζί με κάποιες εντολές προκείμενου να επιτύχουμε ένα συγκεκρίμενο αποτέλεσμα. Για παράδειγμα αν θέλουμε να σβήσουμε όλα τα αρχεία που βρισκόνται στο κατάλογο /home/user και αρχίζουν από a, μπορούμε να δώσουμε την εντολή rm a*.* /home/user. Ας δούμε τους κυριότερους χαρακτήρες μπαλαντέρ.
*:Ταιρίαγμα όλων των χαρακτήρων
?:Ταίριαγμα ενός χαρακτήρα
[]: Ταίριαγμα εύρους χαρακτήρων
!: ’ρνηση εύρους χαρακτήρων

Παραδέιγματα:

*.κατ εννοούμε όλα τα αρχεία με κατάληξη κατ

αμ* εννοούμε τα αρχέια που αρχίζουν με τους χαρακτήρες αμ

α???.* εννοούμε τα αρχεία που αρχίζουν από α έχουν συνολίκα 4 χαρακτήρες και οποιαδήποτε κατάληξη

[αζ]*.* εννοούμε τα αρχεία που έχουν για πρώτο γράμμα α ή ζ και υπόλοιπο οτιδήποτε

α[β-ε]? εννοούμε τα αρχεία τρίων γραμμάτων που έχουν πρώτο γράμμα α, δεύτερο κάποιο εκ των β,γ,δ,ε
και τρίτο γράμμα οτιδήποτε.

Η ιστορία εντολών

Είδαμε οτί το bash διατηρεί ιστορίκο των εντολών που έχουμε πληκτρολόγησει. Για να δούμε την ιστορία των εντολών του bash αρκει να δώσουμε την εντολή history. Μπορούμε να μετακινούμαστε σε αυτές τις εντολές με τα βέλακια πάνω κάτω, η να προσδιορίσουμε κάποια συγκεκριμένη εντολή δινόντας $ !ν όπου ν α αριθμός θέσης της εντολής. Παραδείγματος χάριν μπορούμε να επαναλάβουμε την 10η εντολη που πληκτρολογήσαμε γράφοντας $ !10 . Για να επαναλάβουμε την τελευταία εντολή που πληκτρολογήσαμε αρκεί να δώσουμε $ !! . Το πλήθος των εντολών που θυμάται το bash εξαρτάται από την μεταβλητή HISTSIZE, η οποία από προεπιλογή κρατάει τις 100 τελευταίες εντόλες.

Πολυεπεξεργασία στην γραμμή εντολών

Όσο και αν φαίνεται περίεργο η γραμμή εντολών του bash, εχεί δυνατότητες πολυεπεξεργασίας (multitasking) που σημαίνει πως όπως και στο γραφικό περιβάλλον μπορείτε να εκτελείτε παραπάνω απο μια εργασία και να αλλαζετε την τρέχουσα εργασία σε οποία άλλη θέλετε χωρίς να την τερματίσετε.
Έστω οτί θέλετε να πάρετε μια λίστα με όλα τα αρχεία στο σύστημα που ανήκουν στον χρήστη ή την ομάδα root. Συμβατικά θα εκτελούσατε την εντολή: $ (ls -R /|grep "root") > list 2> errors . Παρολάαυτα η συγκεκρίμενη εντολή σε ένα πολύ μεγάλο ή ενα πολύ αργο συστήμα θα μπορούσε να πάρει αρκετη ώρα μέχρι να εκτελεστέι. Σε ένα σύγχρονο λειτουργικό σαν το Linux, μπορείτε να βάλετε την εντολή να εκτελείται στο παρασκήνιο ενώ εσείς κάνετε chat με το BitchX. Έτσι στο τέλος της προηγούμενης εντολής προσθέτουμε το & , και έτσι το bash καταλαβαίνει οτι πρέπει να την εκτελέσει στο παρασκήνιο. Έτσι εκτελώντας την εντολή: $ (ls -R /|grep "root") > list 2> errors & ,το bash Θα μας επιστρέψει κατευθείαν στην γραμμή εντολών δίνωντας ως έξοδο τον αριθμό της εργασίας μέσα σε αγκύλες, πχ [2] αν είναι η δευτέρη εργασία που εκτελούμε στο παρασκήνιο και των ειδικο κωδικό της πχ 453, που θα δούμε αργότερα τι ακριβως τον χρειαζόμαστε. Για να δούμε μια λίστα με τις διαθέσιμες εργασίες χρησιμοποιούμε την εντολή jobs χωρίς ορίσματα. Για να φέρουμε κάποια από τις εργασίες στο προσκήνιο χρησιμοποιούμε την εντολη fg ακολουθούμενη απο %ν οπου ν ο αριθμός της εργασάς όπως εμφανίζεται στις αγκύλες. Πατώντας CTRL+Z, μπορούμε να θέσουμε προσωρινά μια εργασία σε κατάσταση αναμόνης, δηλαδή ουτέ δουλεύει, αλλά και ούτε έχει τερματιστεί. Αν θέλουμε να την ενεργοποιήσουμε ξανά στο παρασκήνιο χρησιμοποιούμε την εντολή bg %ν, όπου ν ο αριθμός της εργασίας. Αν θέλουμε να τερματίσουμε τελείως μια εργασία μπορουμε να δώσουμε την εντολή kill %v ή kill nnn, οπού ν ο αριθμός της εργασίας και nnn ο κωδικός της.

Keywords: Linux, Terminal, Shell, Commands, Syntax, Tips n Tricks, Terminal Series, multitasking,
pipes,redirection,combine,advanced,features,history,regular expressions,stdout,stdin,stderr

No comments: