Σε αυτήν την ενότητα, θα μάθετε για τους βρόχους για, ενώ και μέχρι. Γιατί δεν εκτελείται ο βρόχος for στον βρόχο bash έξοδος Για κατάλογο

Κύκλος Γιαελαφρώς διαφορετικό από τα ανάλογα σε άλλες γλώσσες προγραμματισμού. Πρώτα απ 'όλα, σας παρέχει τη δυνατότητα να εκτελέσετε διαδοχικές ενέργειες σε "λέξεις" σε μια συμβολοσειρά.

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

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

Αν υποθέσετε ότι το while και το μέχρι είναι πολύ παρόμοια, έχετε δίκιο.

7.1 Παράδειγμα βρόχου

#! / bin / bash για i σε $ (ls); do echo item: $ έκανα

Στη δεύτερη γραμμή, αντιπροσωπεύουμε το i ως μια μεταβλητή που λαμβάνει τις διάφορες τιμές που περιέχονται στο $ (ls).

Η τρίτη γραμμή θα μπορούσε να είναι μεγαλύτερη εάν είναι απαραίτητο. ή μπορεί να υπάρχουν πολλές γραμμές πριν γίνει (4η γραμμή).

Το "done" (4η γραμμή) υποδεικνύει ότι ο κωδικός που χρησιμοποιεί την τιμή του $ i τελειώνει και το $ i παίρνει μια νέα τιμή.

Αυτό το σενάριο έχει μικρή σημασία. Μια πιο χρήσιμη χρήση του βρόχου for θα ήταν να τον χρησιμοποιήσετε για να επιλέξετε μόνο συγκεκριμένα αρχεία στο προηγούμενο παράδειγμα.

7.2 C-όπως για

Ο fiesh πρότεινε την προσθήκη αυτής της φόρμας βρόχου. Αυτός είναι ένας βρόχος for, πιο παρόμοιος με το for στο C, Perl και παρόμοια.

#! / bin / bash για i σε `seq 1 10`; do echo $ έκανα

7.3 Ένα παράδειγμα βρόχου while:

#! / bin / bash ΜΕΤΡΗΤΗΣ = 0 ενώ [$ COUNTER -lt 10]; do echo Ο μετρητής είναι $ COUNTER ας COUNTER = COUNTER + 1 γίνει

Αυτό το σενάριο «μιμείται» τη γνωστή (σε C, Pascal, perl κ.λπ.) δομή «for».

Μια γρήγορη περίληψη της διαφοράς στους τύπους κύκλων:

for - θα εκτελέσει μια ενέργεια εφόσον υπάρχουν αντικείμενα προς εκτέλεση (για παράδειγμα, ανάγνωση ροής από stdin, αρχείο ή συνάρτηση).
ενώ - εκτελεί την ενέργεια μέχρι κατάστασηείναι αλήθεια;
έως - θα εκτελεστεί μέχρι κατάστασηδεν θα γίνει αληθινό, δηλ. ενώ είναι ψευδής.

βρόχος ΓΙΑ

Εξετάστε αυτήν την έκδοση ενός σεναρίου με βρόχο:

$ cat loop.sh #! / bin / bash για μεταβλητή σε `ls -1` do echo" $ μεταβλητή "ολοκληρώθηκε

Η σύνταξη είναι πολύ απλή και φαίνεται ξεκάθαρα στο παράδειγμα:

for (start the loop) μεταβλητή (δηλώστε τη μεταβλητή που θα εκτελεστεί) στο (στείλτε τη ροή στον βρόχο) `ls -1` (η εντολή που πρέπει να εκτελεστεί και να περάσει στη μεταβλητή $). Do και done είναι το "σώμα" του βρόχου, εντός του οποίου θα εκτελεστούν οι κύριες ενέργειες στα ληφθέντα δεδομένα και η ηχώ "$ variable" είναι η πραγματική ενέργεια που εκτελείται από τον βρόχο.

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

$ cat loop.sh #! / bin / bash ls = `ls -1` για μεταβλητή σε $ ls do echo" $ μεταβλητή "ολοκληρώθηκε

Τώρα η εντολή ls -1 μεταβιβάζεται σε μια ξεχωριστή μεταβλητή, η οποία επιτρέπει μεγαλύτερη ευελιξία στην εργασία με τον βρόχο. Αντί για μια μεταβλητή σε έναν βρόχο, μπορείτε επίσης να χρησιμοποιήσετε μια συνάρτηση:

$ cat loop.sh #! / bin / bash lsl () (ls -1) για μεταβλητή σε `lsl` do echo" $ μεταβλητή "ολοκληρώθηκε

Η βασική προϋπόθεση του βρόχου for είναι ότι θα εκτελεστεί εφόσον η εντολή που μεταβιβάζεται σε αυτόν περιέχει αντικείμενα για δράση. Με βάση το παραπάνω παράδειγμα - εφόσον υπάρχουν αρχεία προς εμφάνιση στη λίστα ls -1 - ο βρόχος θα τα μεταβιβάσει σε μια μεταβλητή και θα εκτελέσει το "σώμα βρόχου". Μόλις τελειώσει η λίστα των αρχείων στον κατάλογο, ο βρόχος θα τερματίσει την εκτέλεσή του.

Ας περιπλέκουμε λίγο το παράδειγμα.

Ο κατάλογος περιέχει μια λίστα αρχείων:

$ ls -1 αρχείο1 αρχείο2 αρχείο3 αρχείο4 αρχείο5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

Πρέπει να διαλέξουμε από αυτά μόνο εκείνα που δεν έχουν τη λέξη " όχι«:

$ cat loop.sh #! / bin / bash lsl = `ls -1` για μεταβλητή σε $ lsl do echo" $ μεταβλητή "| grep -v "όχι" έγινε $ ./loop.sh file1 file2 file3 file4 file5 loop.sh

Στον βρόχο, μπορείτε επίσης να χρησιμοποιήσετε εκφράσεις υπό όρους ( εκφράσεις υπό όρους) [...] Για να ελέγξετε τις συνθήκες και μια δήλωση διακοπής για να διακόψετε τον βρόχο εάν ενεργοποιηθεί η συνθήκη.

Εξετάστε αυτό το παράδειγμα:

$ cat loop.sh #! / bin / bash lsl = `ls -1` για μεταβλητή σε $ lsl κάντε εάν [$ variable! =" loop.sh "] τότε echo" $ μεταβλητή "| grep -v "όχι" άλλο σπάσιμο fi έγινε

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

$ ./loop.sh αρχείο1 αρχείο2 αρχείο3 αρχείο4 αρχείο5

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

$ cat loop.sh #! / bin / bash για ((count = 1; count<11; count++)) do echo "$count" done

Εδώ ορίζουμε τρεις εντολές ελέγχου - count = 1, συνθήκη ελέγχου - ενώ η μέτρηση είναι μικρότερη από 11 και η εντολή για εκτέλεση - count +1:

βρόχους WHILE και UNTIL

Ένα απλό παράδειγμα που δείχνει καλά πώς λειτουργεί ο βρόχος while:

$ cat loop.sh #! / bin / bash count = 0 ενώ [$ count -lt 10] do ((count ++)) echo $ count ολοκληρωμένο

Θέτουμε τη μεταβλητή $ count στο μηδέν και, στη συνέχεια, ξεκινάμε τον βρόχο whi le με τη συνθήκη "ενώ ο αριθμός $ είναι μικρότερος από δέκα, εκτελέστε τον βρόχο". Στο σώμα του βρόχου, εκτελούμε postfix προσαύξηση+1 στη μεταβλητή count $ και εκτυπώστε το αποτέλεσμα στο stdout.

Αποτέλεσμα εκτέλεσης:

$ ./loop.sh 1 2 3 4 5 6 7 8 9 10

Μόλις η τιμή της μεταβλητής $ count έγινε 10, ο βρόχος έληξε.

Ένα καλό παράδειγμα ενός "άπειρου" βρόχου που δείχνει πώς λειτουργεί ενώ:

$ cat loop.sh #! / bin / bash count = 10 ενώ [1 = 1] do ((count ++)) echo $ count done $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^ C

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

$ cat loop.sh #! / bin / bash count = 0 έως ότου γίνει [$ count -gt 10] ((count ++)) echo $ count ολοκληρωθεί

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

$ ./loop.sh 1 2 3 4 5 6 7 8 9 10 11

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

$ cat loop.sh #! / bin / bash count = 10 έως ότου το [1 = 1] κάνει ((count ++)) echo $ count ολοκληρωθεί $ ./loop.sh $

Επειδή " κατάσταση"Αρχικά" αληθώς"- το σώμα του βρόχου δεν θα εκτελεστεί.

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

$ cat loop.sh #! / bin / bash check_tomcat_status () (RUN = `ps aux | grep tomcat | grep -v grep | grep java | awk" (εκτύπωση $ 2) "`) ενώ check_tomcat_status κάντε εάν [-n " $ RUN "] και στη συνέχεια printf" ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το Tomcat εξακολουθεί να λειτουργεί με PID $ RUN." else printf "Το Tomcat σταμάτησε, συνεχίζει ... nn" break fi τελειώσει

Αποτέλεσμα εκτέλεσης:

$ ./loop.sh ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το Tomcat εξακολουθεί να λειτουργεί με PID 14435 26548. ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το Tomcat εξακολουθεί να λειτουργεί με PID 14435 26548. ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το Tomcat εξακολουθεί να λειτουργεί με PID 14435 26548. ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το Tomcat εξακολουθεί να τρέχει με PID 14435 26548. ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το Tomcat εξακολουθεί να τρέχει με PID 14435 26548. τρέχει με PID 14435 26548. ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η Tomcat εξακολουθεί να λειτουργεί με PID 14435 26548. ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η Tomcat εξακολουθεί να λειτουργεί με PID 14435 26548. ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η Tomcat εξακολουθεί να λειτουργεί με PID 14435

Πλήρη έκδοση:

Check_tomcat_status () (RUN = `ps aux | grep tomcat | grep -v grep | grep java | awk" (εκτύπωση $ 2) "`) ενώ check_tomcat_status; κάντε εάν [-n "$ RUN"] τότε printf "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το Tomcat εξακολουθεί να λειτουργεί με PID $ RUN. Σταματήστε το;" απαντήστε "Διακοπή Tomcat ..." "Συνέχεια εγκατάστασης ..." && $ CATALINA_HOME / bin / shutdown. sh 2 &> 1 / dev / null || διακοπή ύπνου 2 εάν [-n "$ RUN"] τότε printf "Το Tomcat εξακολουθεί να λειτουργεί. Σκοτώστε το;" απαντήστε "Killing Tomcat ..." "Συνέχεια εγκατάστασης ... n" && kill $ RUN || διακοπή ύπνου 2 fi other printf "Το Tomcat σταμάτησε, συνεχίζει ... nn" break fi τελειώσει

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

Απάντηση () (κατά την ανάγνωση της απάντησης, επαναλάβετε την περίπτωση $ απάντηση σε |) printf "$ 1n" επιστροφή 0 διάλειμμα ;; |) printf "$ 2n" επιστροφή 1 διάλειμμα ;; *) printf "Παρακαλώ, πληκτρολογήστε Y (ναι) ή Ν (όχι)!"

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

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

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

Επανάληψη σε απλές τιμές

Ίσως το απλούστερο παράδειγμα ενός βρόχου for σε σενάρια bash είναι η επανάληψη σε μια λίστα απλών τιμών:

#! / bin / bash για var στο πρώτο δεύτερο τρίτο τρίτο τέταρτο πέμπτο do echo Το στοιχείο $ var έγινε
Τα αποτελέσματα αυτού του σεναρίου φαίνονται παρακάτω. Φαίνεται ξεκάθαρα ότι στοιχεία από τη λίστα εισάγονται διαδοχικά στη μεταβλητή $ var. Αυτό συμβαίνει έως ότου ο κύκλος φτάσει στον τελευταίο από αυτούς.


Απλό για βρόχο

Λάβετε υπόψη ότι η μεταβλητή $ var διατηρεί την αξία της κατά την έξοδο από τον βρόχο, τα περιεχόμενά της μπορούν να αλλάξουν, γενικά, μπορείτε να εργαστείτε μαζί της όπως και με οποιαδήποτε άλλη μεταβλητή.

Επανάληψη σε μιγαδικές τιμές

Η λίστα που χρησιμοποιείται για την προετοιμασία του βρόχου for μπορεί να περιέχει όχι μόνο απλές συμβολοσειρές που αποτελούνται από μία λέξη, αλλά και ολόκληρες φράσεις, οι οποίες περιλαμβάνουν πολλές λέξεις και σημεία στίξης. Για παράδειγμα, όλα μπορεί να μοιάζουν με αυτό:

#! / bin / bash για var στο πρώτο "the second" "the τρίτο" "I'll do it" do echo "This is: $ var" done
Αυτό συμβαίνει αφού αυτός ο βρόχος περάσει από τη λίστα. Όπως μπορείτε να δείτε, το αποτέλεσμα είναι αρκετά αναμενόμενο.


Επανάληψη σε μιγαδικές τιμές
TNW-CUS-FMP - ένας κωδικός προσφοράς για έκπτωση 10% στις υπηρεσίες μας, διαθέσιμος για ενεργοποίηση εντός 7 ημερών "

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

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

#! / bin / αρχείο bash = "myfile" για var σε $ (αρχείο cat $) ηχώ "$ var" έγινε
Αυτό το παράδειγμα χρησιμοποιεί την εντολή cat για να διαβάσει τα περιεχόμενα ενός αρχείου. Η λίστα τιμών που προκύπτει μεταβιβάζεται στον βρόχο και εμφανίζεται. Λάβετε υπόψη ότι το αρχείο στο οποίο αναφερόμαστε περιέχει μια λίστα λέξεων διαχωρισμένων με χαρακτήρες ροής γραμμής, δεν χρησιμοποιούνται κενά.


Βρόχος που διέρχεται από τα περιεχόμενα του αρχείου

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

Κι αν δεν είναι αυτό που θέλετε καθόλου;

Διαχωριστές πεδίου

Ο λόγος για την παραπάνω ιδιαιτερότητα βρίσκεται σε μια ειδική μεταβλητή περιβάλλοντος που ονομάζεται IFS (Internal Field Separator) που σας επιτρέπει να καθορίσετε διαχωριστές πεδίων. Από προεπιλογή, το bash αντιμετωπίζει τους ακόλουθους χαρακτήρες ως οριοθέτες πεδίων:
  • Χώρος
  • Χαρακτήρας καρτέλας
  • Χαρακτήρας τροφοδοσίας γραμμής
Εάν το bash συναντήσει οποιονδήποτε από αυτούς τους χαρακτήρες στα δεδομένα, υποθέτει ότι η επόμενη ανεξάρτητη τιμή στη λίστα βρίσκεται μπροστά του.

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

IFS = $ "\ n"
Μετά την προσθήκη αυτής της εντολής σε ένα σενάριο bash, θα λειτουργήσει όπως αναμένεται, αγνοώντας κενά και καρτέλες και αντιμετωπίζοντας μόνο τις τροφοδοσίες γραμμής ως οριοθέτες πεδίων.

#! / bin / αρχείο bash = "/ etc / passwd" IFS = $ "\ n" για var σε $ (αρχείο cat $) ηχώ "$ var" έγινε
Εάν εκτελέσετε αυτό το σενάριο, θα παράγει ακριβώς αυτό που απαιτείται από αυτό, δίνοντας, σε κάθε επανάληψη του βρόχου, πρόσβαση στην επόμενη γραμμή που θα εγγραφεί στο αρχείο.


Ανίχνευση ενός αρχείου γραμμή προς γραμμή σε έναν βρόχο for

Άλλοι χαρακτήρες μπορούν να χρησιμοποιηθούν ως οριοθέτες. Για παράδειγμα, παραπάνω εμφανίσαμε τα περιεχόμενα του αρχείου / etc / passwd. Τα δεδομένα χρήστη σε συμβολοσειρές διαχωρίζονται με άνω και κάτω τελείες. Εάν χρειάζεται να επεξεργαστείτε τέτοιες γραμμές σε βρόχο, το IFS μπορεί να ρυθμιστεί ως εξής:

Παράκαμψη αρχείων που περιέχονται σε έναν κατάλογο

Μία από τις πιο κοινές χρήσεις των βρόχων for σε σενάρια bash είναι η διέλευση αρχείων σε έναν κατάλογο και η επεξεργασία αυτών των αρχείων.

Για παράδειγμα, δείτε πώς να καταχωρίσετε αρχεία και φακέλους:

#! / bin / bash για αρχείο in / home / likegeeks / * κάντε εάν [-d "$ file"] τότε echo "$ file is a directory" elif [-f "$ file"] και μετά echo "$ file is a αρχείο "Fi τελειώσαμε
Εάν έχετε καταλάβει από αυτήν τη σειρά άρθρων, θα πρέπει να κατανοήσετε τη δομή της κατασκευής if-then, καθώς και πώς να διακρίνετε ένα αρχείο από έναν φάκελο. Εάν δυσκολεύεστε να κατανοήσετε τον παραπάνω κώδικα, διαβάστε ξανά αυτό το υλικό.

Αυτό θα βγει το σενάριο.


Έξοδος των περιεχομένων ενός φακέλου

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

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

C-style για θηλιές

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

Για (i = 0; i< 10; i++) { printf("number is %d\n", i); }
Στα σενάρια bash, μπορείτε να χρησιμοποιήσετε βρόχους για, η περιγραφή των οποίων μοιάζει πολύ με βρόχους τύπου C, αν και υπάρχουν ορισμένες διαφορές εδώ. Το διάγραμμα βρόχου με παρόμοια προσέγγιση μοιάζει με αυτό:

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

Για ((a = 1; α< 10; a++))
Και εδώ είναι ένα παράδειγμα εργασίας:

#! / bin / bash για ((i = 1; i<= 10; i++)) do echo "number is $i" done
Αυτός ο κωδικός θα εκτυπώσει μια λίστα με αριθμούς από το 1 έως το 10.

Στυλ C looping

Ενώ βρόχος

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

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

Ας ρίξουμε μια ματιά σε ένα παράδειγμα σεναρίου με τέτοιο βρόχο:

#! / bin / bash var1 = 5 ενώ το [$ var1 -gt 0] κάνει echo $ var1 var1 = $ [$ var1 - 1] ολοκληρωθεί
Στην είσοδο του βρόχου, ελέγχεται εάν η μεταβλητή $ var1 είναι μεγαλύτερη από το μηδέν. Αν ναι, εκτελείται το σώμα του βρόχου, στο οποίο αφαιρείται ένα από την τιμή της μεταβλητής. Αυτό συμβαίνει σε κάθε επανάληψη, ενώ εκτυπώνουμε την τιμή της μεταβλητής στην κονσόλα πριν την τροποποιήσουμε. Μόλις το $ var1 είναι 0, ο βρόχος τελειώνει.

Το αποτέλεσμα του βρόχου while

Εάν δεν τροποποιήσετε τη μεταβλητή $ var1, αυτό θα οδηγήσει στο να πέσει το σενάριο σε έναν άπειρο βρόχο.

Φωλιασμένοι βρόχοι

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

#! / bin / bash για ((a = 1; α<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
Παρακάτω είναι τι θα βγει αυτό το σενάριο. Όπως μπορείτε να δείτε, πρώτα εκτελείται η πρώτη επανάληψη του εξωτερικού βρόχου, μετά τρεις επαναλήψεις του εσωτερικού βρόχου, μετά την ολοκλήρωσή του, ο εξωτερικός βρόχος μπαίνει ξανά στο παιχνίδι και μετά πάλι ο εσωτερικός βρόχος.

Φωλιασμένοι βρόχοι

Επεξεργασία περιεχομένου αρχείου

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

#! / bin / bash IFS = $ "\ n" για καταχώριση σε $ (cat / etc / passwd) do echo "Values ​​in $ entry -" IFS =: για την τιμή στην καταχώρηση $ κάντε echo "$ value" Έγινε
Υπάρχουν δύο βρόχοι σε αυτό το σενάριο. Το πρώτο κυκλώνεται μέσω των γραμμών, χρησιμοποιώντας τον χαρακτήρα τροφοδοσίας γραμμής ως διαχωριστικό. Το εσωτερικό είναι απασχολημένο με την ανάλυση συμβολοσειρών, τα πεδία των οποίων χωρίζονται με άνω και κάτω τελεία.

Επεξεργασία δεδομένων αρχείων

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

Έλεγχος κύκλου

Ίσως, μετά την εισαγωγή του βρόχου, θα χρειαστεί να τον σταματήσετε όταν η μεταβλητή βρόχου φτάσει σε μια συγκεκριμένη τιμή, η οποία δεν αντιστοιχεί στην αρχικά καθορισμένη συνθήκη για το τέλος του βρόχου. Θα χρειαστεί σε μια τέτοια κατάσταση να περιμένουμε την κανονική ολοκλήρωση του κύκλου; Φυσικά όχι, και σε τέτοιες περιπτώσεις είναι χρήσιμες οι ακόλουθες δύο εντολές:
  • Διακοπή
  • να συνεχίσει

Εντολή διακοπής

Αυτή η εντολή σας επιτρέπει να διακόψετε την εκτέλεση του βρόχου. Μπορεί να χρησιμοποιηθεί τόσο για βρόχους όσο και για βρόχους while:

#! / bin / bash για var1 σε 1 2 3 4 5 6 7 8 9 10 κάντε εάν [$ var1 -eq 5] και μετά σπάστε το fi echo "Number: $ var1" ολοκληρωμένο
Ένας τέτοιος βρόχος, υπό κανονικές συνθήκες, θα περάσει από ολόκληρη τη λίστα τιμών από τη λίστα. Ωστόσο, στην περίπτωσή μας, η εκτέλεσή της θα διακοπεί όταν η μεταβλητή $ var1 ισούται με 5.

Αφήνοντας νωρίς τον βρόχο for

Εδώ είναι το ίδιο πράγμα για τον βρόχο while:

#! / bin / bash var1 = 1 ενώ [$ var1 -lt 10] κάντε εάν [$ var1 -eq 5], στη συνέχεια, διακόψτε το fi echo "Επανάληψη: $ var1" var1 = $ (($ var1 + 1)) ολοκληρωθεί
Η εντολή break που εκτελείται όταν η τιμή του $ var1 ισούται με 5 διακόπτει τον βρόχο. Η κονσόλα θα έχει την ίδια έξοδο όπως στο προηγούμενο παράδειγμα.

Συνέχεια εντολής

Όταν αυτή η εντολή συναντάται στο σώμα του βρόχου, η τρέχουσα επανάληψη τελειώνει νωρίς και ξεκινά η επόμενη και ο βρόχος δεν εξέρχεται. Ας ρίξουμε μια ματιά στην εντολή συνέχεια στον βρόχο for:

#! / bin / bash για ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Όταν πληρούται η συνθήκη μέσα στον βρόχο, δηλαδή όταν το $ var1 είναι μεγαλύτερο από 5 και μικρότερο από 10, το κέλυφος θα εκτελέσει την εντολή συνέχεια. Αυτό οδηγεί στην παράβλεψη των υπόλοιπων εντολών στο σώμα του βρόχου και στη συνέχεια στην επόμενη επανάληψη.

Η εντολή συνέχεια σε έναν βρόχο for

Έξοδος επεξεργασίας που εκτελείται σε βρόχο

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

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

#! / bin / bash για ((a = 1; α< 10; a++)) do echo "Number is $a" done >myfile.txt echo "ολοκληρώθηκε".
Το περιτύλιγμα θα δημιουργήσει το αρχείο myfile.txt και θα ανακατευθύνει την έξοδο της κατασκευής for σε αυτό το αρχείο. Ας ανοίξουμε το αρχείο και ας βεβαιωθούμε ότι περιέχει ακριβώς αυτό που αναμένεται.

Ανακατεύθυνση της εξόδου ενός βρόχου σε ένα αρχείο

Παράδειγμα: αναζήτηση για εκτελέσιμα αρχεία

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

#! / bin / bash IFS =: για φάκελο στο $ PATH κάντε echo "$ folder:" για αρχείο στο φάκελο $ / * κάντε εάν [-x $ file], στη συνέχεια, echo "$ file" fi ολοκληρωμένο
Ένα τέτοιο σενάριο, μικρό και απλό, κατέστησε δυνατή τη λήψη μιας λίστας εκτελέσιμων αρχείων που είναι αποθηκευμένα σε φακέλους από το PATH.

Αναζήτηση για εκτελέσιμα αρχεία σε φακέλους από τη μεταβλητή PATH

Αποτελέσματα

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

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

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

Για βρόχο

Κύκλος Για v κτυπώ δυνατάέχει δύο τύπους. Ας εξετάσουμε πρώτα την κλασική έκδοση Για... Η γενική άποψη έχει ως εξής:

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

Και εδώ είναι ένα πρακτικό παράδειγμα:

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

Το αποτέλεσμα θα είναι το ίδιο όπως στο πρώτο παράδειγμα.

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

Αποτέλεσμα:

Ας επιστρέψουμε στο δεύτερο είδος Για... Συχνά στα σενάρια μπορείτε να βρείτε τη λεγόμενη παραλλαγή τύπου C Γιαπου χρησιμοποιείται για βρόχους που βασίζονται σε αριθμούς. Ας εξετάσουμε αμέσως ένα παράδειγμα:

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

Πρακτικό παράδειγμα:

#! / bin / bash
i = 1
ενώ [$ i -lt 7]
κάνω
ηχώ $ i
έστω i = i + 1
Έγινε

Στο παράδειγμά μας, ελέγχεται ότι η μεταβλητή Εγώλιγότερο (-lt), αριθμός 7 και αν ναι, τότε εμφανίζεται η τιμή της μεταβλητής. Εκφραση έστω i = i + 1, αυξάνει τη μεταβλητή κατά ένα, ελέγχει ξανά και ούτω καθεξής. let λέει στον διερμηνέα να αντιμετωπίζει τα ορίσματα ως αριθμητικές τιμές. Αυτή η γραμμή θα μπορούσε να γραφτεί ως ας ++(επιλογή τύπου c). Με αύξηση του αριθμού κατά περισσότερες από μία, μπορείτε να το γράψετε ως εξής: έστω i + = 2- σε αυτήν την περίπτωση Εγώθα αυξηθεί σε βήματα του 2. Μια άλλη επιλογή για την αύξηση μιας μεταβλητής είναι η χρήση της ενσωματωμένης αριθμομηχανής (λειτουργεί μόνο με ακέραιους αριθμούς). Η πρόσβαση στην αριθμομηχανή είναι δυνατή μέσω διπλών αγκύλων: i = $ (($ i + 1))ή μέσω τετράγωνων: i = $ [$ i + 1]Μπορείτε επίσης να χρησιμοποιήσετε την αριθμομηχανή στη γραμμή εντολών:

Με τους βρόχους, πρέπει να προσέχετε να μην έχετε την επιλογή ενός άπειρου βρόχου. Παρεμπιπτόντως για τον εντοπισμό σφαλμάτων κτυπώ δυνατά scripts, μπορείτε να αλλάξετε την πρώτη γραμμή σε #! / bin / bash -xή εκτελέστε το σενάριο με την εντολή bash -χ:

[email προστατευμένο]: ~ / linux $ bash -x ./testfor.sh
+ i = 1
+ "[" 1 -gt 5 "]"
+ ηχώ i = 1
i = 1
+ έστω i = i + 1
+ '[' 2 -gt 5 ']'
+ ηχώ i = 2
i = 2
+ έστω i = i + 1
+ '[' 3 -gt 5 ']'
+ ηχώ i = 3
i = 3
+ έστω i = i + 1
+ '[' 4 -gt 5 ']'
+ ηχώ i = 4
i = 4
+ έστω i = i + 1
+ '[' 5 -gt 5 ']'
+ ηχώ i = 5
i = 5
+ έστω i = i + 1
+ '[' 6 -gt 5 ']'

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

Λειτουργίες στο bash

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

Πρώτος τρόπος:

συνάρτηση συνάρτηση_όνομα
{
σώμα λειτουργίας
}

Δεύτερος τρόπος:

όνομα_λειτουργίας ()
{
σώμα λειτουργίας
}

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

#! / bin / bash
αστάρι λειτουργίας
{
εάν [$ # -ne 0]
τότε
τοπικό a = 1
echo "Αριθμός παραμέτρων που πέρασαν - $ #"
για εγω μεσα [email προστατευμένο]
κάνω
echo "$ a-th παράμετρος είναι $ i"
αφήστε ένα ++
Έγινε
επιστροφή 0
αλλού
echo "Δεν έχουν περάσει παράμετροι"
επιστροφή 1
fi
}
echo "Κλήση της συνάρτησης με παραμέτρους:"
αστάρι α β γ
ηχώ $;
echo "Κλήση της συνάρτησης χωρίς παραμέτρους:"
αλφαβητάρι
ηχώ $;

Σε αυτό το παράδειγμα, μια συνάρτηση με το όνομα αλφαβητάρι... Κλήση συνάρτησης με παραμέτρους: αστάρι α β γκαι χωρίς παραμέτρους: αλφαβητάρι... Στο σώμα της συνάρτησης, όλες οι κατασκευές θα πρέπει να σας είναι οικείες, με εξαίρεση $# , $ iκαι [email προστατευμένο] .$# - επιστρέφει τον αριθμό των παραμέτρων που μεταβιβάστηκαν στη συνάρτηση. Στο παράδειγμά μας, αυτός θα είναι ο αριθμός 3 .[email προστατευμένο] επιστρέφει όλες τις παραμέτρους σε μία γραμμή. Στο παράδειγμα θα ήταν α β γ... Και μετά $1 , $2 , $3 και τα λοιπά. μπορείτε να αντιμετωπίσετε κάθε παράμετρο προσωπικά. $? - περιέχει τον κωδικό για την εκτέλεση της τελευταίας εντολής. Στο παράδειγμά μας, ο κώδικας για την εκτέλεση της συνάρτησης.

Η συνάρτηση μπορεί επίσης να επιστρέψει μια αριθμητική τιμή μέσω μιας λέξης-κλειδιού ΕΠΙΣΤΡΟΦΗ... Κατά κανόνα, επιστρέφουν 0 εάν η συνάρτηση εκτελέστηκε χωρίς σφάλματα ή μια μη μηδενική τιμή εάν κάτι πήγε στραβά. Στο παράδειγμα, εάν μια συνάρτηση καλείται με παραμέτρους, επιστρέφεται η τιμή 0 και εάν η συνάρτηση κλήθηκε χωρίς παραμέτρους, τότε θα επιστραφεί ο κωδικός 1.

Τα πάντα σχετικά με τη μετάδοση παραμέτρων σε μια συνάρτηση λειτουργούν το ίδιο για ένα σενάριο. Το σενάριο μπορεί επίσης να περάσει παραμέτρους με τον ίδιο τρόπο και να τις χειριστεί με τον ίδιο τρόπο χρησιμοποιώντας $#, [email προστατευμένο], $ N... Από την ίδια κατηγορία και επιλογή - $0 - που επιστρέφει το όνομα της εντολής που ξεκίνησε το σενάριο. Εάν το σενάριο εκτελέστηκε από την εντολή ./script.shμετά ηχώ $0 θα επιστρέψει την τιμή ./script.sh, και εάν υπάρχει εντολή /home/igor/linux/script.shτότε η τιμή θα επιστραφεί /home/igor/linux/script.sh.