Διαδρομές
/
Bash
Bash
/
Ύλη
/
Εντολές και ορίσματα
Εν

Εντολές και ορίσματα σε Bash

{one: "1 άσκηση", other: "%{count} ασκήσεις"}

Σχετικά με την έννοια Εντολές και ορίσματα

Φλοιοί

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

Υπάρχουν πολλοί διαφορετικοί φλοιοί γραμμής εντολών. Τα Windows προσφέρουν τα cmd και powershell. Το Mac και το Linux προσφέρουν "φλοιούς Unix", από τους οποίους υπάρχουν πολλοί. Ο προεπιλεγμένος φλοιός στο Mac είναι ο zsh. Ο csh είναι ένας παλιός φλοιός με σύνταξη παρόμοια με της C. Ο bash είναι ένας από τους πιο δημοφιλείς φλοιούς, ειδικά στο Linux.

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

Ο bash βασίζεται στον φλοιό Bourne. Γι' αυτό ονομάζεται "Bourne-again shell". Είναι ο προεπιλεγμένος φλοιός σε πολλά συστήματα Linux. Ο bash προσφέρει πολλά χαρακτηριστικά που τον κάνουν έναν ευχάριστο διαδραστικό φλοιό, όπως:

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

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

Τα βασικά του bash: εντολές και ορίσματα

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

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

Note

Στα παρακάτω παραδείγματα θα σου δείξουμε μερικές διαδραστικές εντολές που μπορείς να εκτελέσεις.

  • Ο χαρακτήρας # ξεκινά ένα σχόλιο. Όποιες λέξεις ακολουθούν το σχόλιο αγνοούνται από τον φλοιό· το σχόλιο προορίζεται μόνο για ανάγνωση.
  • Ο χαρακτήρας $ δηλώνει το prompt του φλοιού. Αν αντιγράφεις την εντολή, μην συμπεριλάβεις το prompt.
# Note: It is always a good idea to run `ls` before `rm`
# to make sure you know what you are deleting.

$ rm *            # Remove all files in the current directory.
                  # Make sure you run this in a temp directory or you can lose files!
$ ls              # List files in the current directory (no output, no files).
$ touch a   b c   # Create files 'a', 'b' and 'c'.
$ ls              # List files again; this time the outputs: 'a', 'b' and 'c'.
a  b  c

Το rm είναι μια εφαρμογή που διαγράφει τα αρχεία που της δίνονται. Το * είναι ένας χαρακτήρας glob, ένα μοτίβο "μπαλαντέρ" που ταιριάζει με όλα τα αρχεία στον τρέχοντα κατάλογο. Θα μιλήσουμε περισσότερο για τα glob αργότερα.

Πρόσεξες ότι υπάρχουν πολλά κενά ανάμεσα στο a και στο b, και μόνο ένα ανάμεσα στο b και στο c; Το πόσο κενό διάστημα υπάρχει ανάμεσα στα ορίσματα δεν έχει σημασία! Για παράδειγμα:

$ echo This is a test.
This is a test.
$ echo This    is    a    test.
This is a test.

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

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

$ echo "This    is    a    test."
This    is    a    test.

Τα εισαγωγικά ομαδοποιούν ό,τι βρίσκεται μέσα τους σε ένα μοναδικό όρισμα. Το όρισμα είναι This is a test. μαζί με αυτούς τους συγκεκριμένους χαρακτήρες κενού. Σημείωσε ότι τα εισαγωγικά δεν είναι μέρος του ορίσματος· ο bash τα αφαιρεί πριν παραδώσει αυτό το μοναδικό όρισμα στο echo.

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

$ [-f file]
bash: [-f: command not found

Αυτό έχει σκοπό να ελέγξει αν υπάρχει ένα αρχείο με όνομα file. Είναι λογικό να υποθέσει κανείς ότι τα κενά γύρω από το [ και το ] δεν έχουν σημασία, αλλά το [ είναι στην πραγματικότητα μια εντολή και απαιτεί το τελευταίο όρισμά της να είναι ]. (Θα καλύψουμε την εντολή [ με περισσότερες λεπτομέρειες αργότερα.) Επομένως, πρέπει να χωρίσουμε το [ από το -f και το ] από το file. Διαφορετικά, ο bash θα νομίσει ότι προσπαθούμε να εκτελέσουμε μια εντολή με όνομα [-f με ένα μόνο όρισμα, το file]. Η σωστή εντολή χωρίζει όλα τα ορίσματα με κενό:

$ [ -f file ]

(Βλέπουμε πολλούς ανθρώπους να μπερδεύονται με αυτή τη συμπεριφορά· νομίζουν ότι το [...] είναι "απλώς σύνταξη" και ότι μπορούν να παραλείψουν τα κενά· το [ είναι μια εντολή και το κενό είναι απαραίτητο.)

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

$ [ -f "my file" ]

Τύποι εντολών

Ο bash καταλαβαίνει διάφορους τύπους εντολών: aliases, συναρτήσεις, ενσωματωμένες εντολές, λέξεις-κλειδιά και εκτελέσιμα. Όλα αυτά είναι εντολές και συμπεριφέρονται όλα με πολύ παρόμοιο τρόπο.

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

Συναρτήσεις

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

Ενσωματωμένες εντολές

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

Λέξεις-κλειδιά

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

$ [[ "hello world" =~ e.*o ]]   # returns a "success" status
$ [ "hello world" =~ e.*o ]
bash: [: =~: binary operator expected

Οι τελεστές σύγκρισης συμβολοσειρών < και > είναι ένα άλλο παράδειγμα του πώς οι λέξεις-κλειδιά αναλύουν τον κώδικα διαφορετικά. Μέσα σε [[...]], αυτοί οι τελεστές δεν χρειάζονται καμία ιδιαίτερη προσοχή.

$ if [[ "$USER" < "n" ]]; then
    echo "$USER is in the first half of the alphabet"
fi
# => glennj is in the first half of the alphabet

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

$ if [ "$USER" < "n" ]; then
    echo "$USER is in the first half of the alphabet"
fi
# => bash: n: No such file or directory

$ if [ "$USER" \< "n" ]; then
    echo "$USER is in the first half of the alphabet"
fi
# => glennj is in the first half of the alphabet

Εκτελέσιμα

Ο τελευταίος τύπος εντολής που μπορεί να εκτελέσει ο bash είναι ένα εκτελέσιμο. Πρόκειται για εκτελέσιμα αρχεία (προγράμματα) στο σύστημα αρχείων του υπολογιστή σου που μπορείς να τρέξεις. (Τα εκτελέσιμα μπορεί επίσης να ονομάζονται εξωτερικές εντολές ή εφαρμογές.) Τα εκτελέσιμα συνήθως καλούνται πληκτρολογώντας μόνο το όνομά τους· η πλήρης διαδρομή προς το αρχείο συνήθως δεν χρειάζεται. Αυτό γίνεται εφικτό επειδή ο bash χρησιμοποιεί μια προκαθορισμένη μεταβλητή που τον βοηθά να βρει τη θέση των συνηθισμένων εκτελέσιμων αρχείων. Αυτή η μεταβλητή ονομάζεται PATH. Είναι ένα σύνολο ονομάτων καταλόγων χωρισμένων με άνω τελείες (π.χ. /usr/bin:/bin). Όταν δίνεται μια εντολή (π.χ. myprogram ή ls) χωρίς διαδρομή αρχείου (και δεν είναι alias, συνάρτηση, ενσωματωμένη εντολή ή λέξη-κλειδί), ο bash ψάχνει μέσα στους καταλόγους του PATH. Οι κατάλογοι ερευνώνται με τη σειρά, από αριστερά προς τα δεξιά, για να διαπιστωθεί αν περιέχουν ένα εκτελέσιμο με το δεδομένο όνομα.

Αν το εκτελέσιμο βρίσκεται έξω από μια γνωστή διαδρομή, θα πρέπει να προσδιοριστεί η διαδρομή του αρχείου του. Για το εκτελέσιμο myprogram στον τρέχοντα κατάλογο, χρησιμοποίησε ./myprogram· αν βρίσκεται στον κατάλογο /opt/somedirectory, χρησιμοποίησε /opt/somedirectory/myprogram.

Συμβουλή: Η εντολή type μπορεί να χρησιμοποιηθεί για να πάρεις πληροφορίες σχετικά με την εντολή:

$ type rm
rm is hashed (/bin/rm)
# or it might return: `rm is /bin/rm`

$ type cd
cd is a shell builtin

Σενάρια

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

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

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

#!/bin/bash

Αυτή η γραμμή ονομάζεται οδηγία διερμηνευτή (ονομάζεται επίσης hashbang ή shebang). Προσδιορίζει ότι το /bin/bash θα χρησιμοποιηθεί ως ο διερμηνευτής όταν το αρχείο χρησιμοποιηθεί ως εκτελέσιμο σε μια εντολή. Όταν ο πυρήνας του λειτουργικού συστήματος εκτελέσει ένα μη δυαδικό αρχείο, διαβάζει την πρώτη γραμμή του αρχείου. Αν η γραμμή ξεκινά με #!, ο πυρήνας χρησιμοποιεί τη γραμμή για να καθορίσει σε ποιον διερμηνευτή θα προωθήσει το αρχείο. (Υπάρχουν κι άλλοι έγκυροι τρόποι να γίνει αυτό, δες παρακάτω.) Το #! πρέπει να βρίσκεται στην αρχή ακριβώς του αρχείου, χωρίς κενά ή κενές γραμμές πριν από αυτό. Οι εντολές του σεναρίου μας θα εμφανίζονται σε ξεχωριστές γραμμές κάτω από αυτό.

Συμβουλή: Αντί για #!/bin/bash, θα μπορούσες να χρησιμοποιήσεις

#!/usr/bin/env bash

Το env ψάχνει στο $PATH το εκτελέσιμο που ορίζει το πρώτο του όρισμα (στην περίπτωση αυτή, το "bash"). Για πιο αναλυτική εξήγηση αυτής της τεχνικής και του πώς διαφέρει από το απλό #!/bin/bash, δες αυτή την ερώτηση στο StackOverflow.

Μην ξεγελιέσαι από σενάρια ή παραδείγματα στο διαδίκτυο που χρησιμοποιούν το /bin/sh ως διερμηνευτή. Το sh δεν είναι bash! Ο ίδιος ο bash είναι ένας φλοιός "συμβατός με sh", που σημαίνει ότι μπορεί να τρέξει τα περισσότερα σενάρια sh και κουβαλά μεγάλο μέρος της ίδιας σύνταξης. Ωστόσο, το αντίστροφο δεν ισχύει· ορισμένες δυνατότητες του bash θα σπάσουν ή θα προκαλέσουν απροσδόκητη συμπεριφορά στο sh. Στην πραγματικότητα, δεν υπάρχει ένας μοναδικός φλοιός sh. Υπάρχουν πολλές υλοποιήσεις φλοιού που υποστηρίζουν τη σύνταξη POSIX-sh. Ανάλογα με το λειτουργικό σου σύστημα, όταν τρέχεις sh μπορεί στην πραγματικότητα να εκτελείς bash, ash, dash ή κάποιον άλλο φλοιό.

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

$ bash myscript

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

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

$ chmod +x myscript  # Mark the file as executable.
$ ./myscript         # Now, myscript can be executed directly
                     # instead of having to specify bash.

Όταν εκτελούμε την εντολή με αυτόν τον τρόπο, το λειτουργικό σύστημα (OS) χρησιμοποιεί τη γραμμή #! για να καθορίσει ποιον διερμηνευτή θα χρησιμοποιήσει για να τρέξει το σενάριό σου.

Αναγνώριση

Το περιεχόμενο αυτής της ενότητας προέρχεται από το Commands and Arguments στον Bash Guide.

Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα