Για έξοδο bash loop. BASH: περιγραφή των βρόχων for, while, μέχρι και παραδειγμάτων χρήσης

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

για δήλωση βρόχου

Η γενική σύνταξη της δήλωσης for είναι:

για μεταβλητή
κάνω
λίστα εντολών
Έγινε

Ο βρόχος for στο bash είναι αρκετά διαφορετικός από τον βρόχο for σε γλώσσες προγραμματισμού όπως η C ή η PHP. Αν λοιπόν είστε προγραμματιστής C, θα πρέπει να συνηθίσετε αυτές τις διαφορές για να μην μπερδεύεστε.
Ως αποτέλεσμα της αντικατάστασης του προτύπου, λαμβάνεται μια λίστα λέξεων. Σε κάθε επανάληψη, η μεταβλητή παίρνει κάθε επόμενη τιμή αυτής της λίστας και οι εντολές μεταξύ do και done εκτελούνται. Οι επαναλήψεις σταματούν όταν εξαντληθούν οι λέξεις στη λίστα.
$ για την ημέρα στη Δευτ. Τρ. Τετ. Πέμ. Παρ, ολοκληρώθηκε το "Σήμερα $ημέρα".
Οι δεσμευμένες λέξεις της δήλωσης for μπορούν επίσης να γραφτούν σε μία γραμμή, όπως ήταν στην προηγούμενη ανάρτηση για τη δήλωση if. Για να το κάνετε αυτό, βάλτε ";". Ας ξαναγράψουμε το προηγούμενο παράδειγμα έχοντας κατά νου αυτό το χαρακτηριστικό:
$ για την ημέρα στη Δευτ. Τρ. Τετ. Πέμ. do echo "Σήμερα είναι $ημέρα"? Έγινε
Η απουσία κατασκευής ισοδυναμεί με εγγραφή [email προστατευμένο]Σχετικά με την παράμετρο [email προστατευμένο]είπε στο .

ενώ η δήλωση βρόχου

Η γενική σύνταξη της εντολής while είναι:

ενώ λίστα 1
κάνω
λίστα 2
Έγινε

Η λίστα 1 εκτελείται πρώτα. Εάν πετύχει, δηλαδή επιστρέψει τον κωδικό μηδέν, ο έλεγχος περνά στη λίστα2. Οι επαναλήψεις συνεχίζονται έως ότου το αποτέλεσμα της εκτέλεσης της λίστας1 γίνει μη μηδενικό. Για παράδειγμα:
i=10 ενώ [ $i -gt 0 ]; do echo $i i=$(($i-1)) έγινε; ηχώ "τέλος"

μέχρι δήλωση βρόχου

Η γενική σύνταξη της εντολής μέχρι είναι:

μέχρι τη λίστα 1
κάνω
λίστα 2
Έγινε

Η λίστα 1 εκτελείται πρώτα. Εάν αποτύχει, δηλαδή με έναν κωδικό επιστροφής μη μηδενικού, ο έλεγχος περνά στη λίστα2. Οι επαναλήψεις συνεχίζονται έως ότου το αποτέλεσμα της εκτέλεσης της λίστας1 γίνει μηδέν. Για παράδειγμα:
i=10 έως [ $i -lt 0 ]; do echo $i i=$(($i-1)) έγινε; ηχώ "τέλος"

επιλέξτε δήλωση βρόχου

Η γενική σύνταξη της εντολής Select είναι:

επιλέξτε μεταβλητή
κάνω
λίστα
Έγινε

Ως αποτέλεσμα της αντικατάστασης του προτύπου, λαμβάνεται μια λίστα λέξεων. Ο χειριστής προσθέτει σειριακούς αριθμούς σε αυτές τις λέξεις και εξάγει ολόκληρο το σύνολο στην τυπική ροή σφαλμάτων. Η απουσία κατασκευής ισοδυναμεί με εγγραφή [email προστατευμένο]Μετά από αυτό, εμφανίζεται μια προτροπή και διαβάζεται μια γραμμή από την τυπική ροή εισόδου. Εάν η συμβολοσειρά περιέχει έναν αριθμό που αντιστοιχεί σε οποιαδήποτε λέξη από τη λίστα, τότε η μεταβλητή παίρνει αυτόν τον αριθμό ως τιμή. Εάν δεν βρέθηκε κατάλληλη λέξη, τότε η τιμή της μεταβλητής γίνεται κενή συμβολοσειρά. Μετά από αυτό, εκτελείται η λίστα των εντολών και η επανάληψη συνεχίζεται έως ότου βρεθεί ο χαρακτήρας τέλους αρχείου στη γραμμή εισαγωγής ή έως ότου εμφανιστεί break ή return στη λίστα εντολών.
Οι εντολές break και return χρησιμοποιούνται για τον έλεγχο της προόδου του βρόχου. Η εντολή break διακόπτει την εκτέλεση του βρόχου, ενώ το return επιστρέφει έναν κωδικό αποτελέσματος (μηδέν ή μη μηδενικό).
Η δήλωση επιλογής είναι χρήσιμη για τη δημιουργία αριθμημένων μενού. Για παράδειγμα, στον κατάλογο ~/temp υπάρχουν 3 αρχεία: proto.txt, file.txt και readme. Ένα παράδειγμα τμήματος σεναρίου που σας επιτρέπει να προβάλετε γρήγορα οποιοδήποτε από αυτά.
echo "Επιλογή αρχείου για προβολή:" επιλέξτε αρχείο στο ~/temp/* Quit; κάντε εάν [ -f $file ]; στη συνέχεια cat $file? Άλλο διάλειμμα? fi τελειώσει
Εκτελώντας αυτό το σενάριο, θα δούμε στην οθόνη:
Επιλέξτε ένα αρχείο για προβολή:
1) /home/istergul/temp/file.txt
2) /home/istergul/temp/proto.txt
3) /home/istergul/temp/readme
4) Κόψτε

Το επόμενο θέμα θα εξετάσει τις αντικαταστάσεις παραμέτρων υπό όρους. Ανυπομονώ για τα σχόλιά σας.

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

για βρόχο

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

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

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

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

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

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

Αποτέλεσμα:

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

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

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

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

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

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

[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

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

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

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

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

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

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

#!/bin/bash
αστάρι λειτουργίας
{
αν [ $# -ne 0 ]
έπειτα
τοπικό a=1
echo "Αριθμός παραμέτρων που πέρασαν - $#"
για εγω μεσα [email προστατευμένο]
κάνω
ηχώ "$ α-η παράμετρος— $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.

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

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

Κύκλος Γιαέχει σχεδιαστεί για να επαναλαμβάνει τις ενέργειες μέχρι να ολοκληρωθούν όλες. Φανταστείτε, για παράδειγμα, ότι έχετε έναν κατάλογο εικόνων και πρέπει να τις μετατρέψετε από τη μια μορφή στην άλλη. Μπορείτε να χρησιμοποιήσετε έναν βρόχο Γιαμαζί με το πρόγραμμα μετατρέπωαπό τη συσκευασία ImageMagick(ή κάποιο άλλο πρόγραμμα), για παράδειγμα, για τη μετατροπή εικόνων από μορφή JPEG σε μορφή PNG. Ή, για παράδειγμα, μπορεί να χρειαστεί να μετατρέψετε πολλά αρχεία ήχου από MP3 V ΟΓΓ Βορμπής.

Κύκλος ενώχρησιμοποιείται για την επανάληψη ενεργειών Αντίοεκτελείται (είναι αληθής) κάποια προϋπόθεση. Κύκλος μέχριλειτουργεί λίγο διαφορετικά: εκτελεί μια ενέργεια μέχριμέχρι να εκπληρωθεί η προϋπόθεση. Έτσι, για παράδειγμα, μπορείτε να αντιμετωπίσετε και να εκτελέσετε μια ενέργεια μέχριμέχρι να φτάσει η τιμή του το 10. Ας το δούμε αυτό πιο αναλυτικά με παραδείγματα.

Ας ξεκινήσουμε με έναν βρόχο Για. Η μορφή του είναι:

Για το i σε $(εντολή); κάνει εντολή $i; Έγινε

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

#!/bin/bash για i σε $(εντολή); do εντολή $i έγινε

Έτσι, για παράδειγμα, εάν χρειάζεται να το κάνετε αντίγραφα ασφαλείαςόλα τα αρχεία HTML στον κατάλογο, μπορείτε να χρησιμοποιήσετε την ακόλουθη εντολή:

Για i σε $(ls *html); do cp $i $i.bak; Έγινε

Αυτό δημιουργεί μια τοπική μεταβλητή $i, η εντολή εκτελείται ls*html, τα αποτελέσματα του οποίου θα είναι τα δεδομένα που αρχικοποιούν την τιμή της μεταβλητής $iσε κάθε επανάληψη του βρόχου (στο παράδειγμά μας, αυτή θα είναι η λίστα των αρχείων που επιστρέφονται από την εντολή ls, ένα για κάθε επανάληψη). Στη συνέχεια, εκτελείται η εντολή cp, στην οποία μεταβιβάζεται μια μεταβλητή μεταξύ των παραμέτρων $i.

Κάποιος μπορεί να ρωτήσει αν είναι υποχρεωτική η χρήση του γράμματος "Εγώ"ως όνομα μεταβλητής; Οχι. Μπορείτε να χρησιμοποιήσετε οποιοδήποτε έγκυρο βίαιο χτύπημαόνομα μεταβλητής. Φυσικά, είναι καλύτερο να χρησιμοποιείτε πιο ουσιαστικά ονόματα μεταβλητών σε σενάρια, όπως π.χ $εισαγωγήή $html.

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

ενώ και μέχρι

Σκεφτείτε τώρα τις κατασκευές ενώΚαι μέχρι. Επίσης, θα χρησιμοποιήσουμε κάποιες προϋποθέσεις bash. Στο παράδειγμά μας, θα τα χρησιμοποιήσουμε για να προσδιορίσουμε, για παράδειγμα, εάν η τιμή μιας μεταβλητής είναι μεγαλύτερη ή μικρότερη από τον αριθμό X. αν το αρχείο υπάρχει και αν είναι κατάλογος. Μπορείτε επίσης να χρησιμοποιήσετε όρους για να προσδιορίσετε, για παράδειγμα, εάν ένα αρχείο είναι αναγνώσιμο ή έχει ένα bit GID στα δικαιώματά του.

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

#!/bin/bash i=0 ενώ [ $i -lt 22 ] αγγίξτε το $i i=$[$i+1] ολοκληρώθηκε

Αυτό το σενάριο θα δημιουργήσει 22 αρχεία με ονόματα από το 0 έως το 21. Ο βρόχος θα εκτελεστεί μέχρι Αντίομεταβλητή τιμή $iπιο λιγο ( - λ) 22.

Τώρα ας απαλλαγούμε από τα αρχεία που δημιουργούνται με ένα βρόχο μέχρι:

#!/bin/bash i=0 έως ότου ολοκληρωθεί το [ $i -eq 22 ] rm $i i=$[$i+1]

Εδώ έχουμε αντικαταστήσει ενώεπί μέχρι, και στην υπό όρους έκφραση αντικαταστήσαμε "πιο λιγο" (- λ) επί "ίσον" (-εξ). Έτσι, το σενάριό μας θα λειτουργεί όσο η τιμή $iδεν θα φτάσει τα 22. Και αντί για αφήσυνηθίζαμε rmγια να διαγράψετε αρχεία αντί να τα δημιουργήσετε. Απλό, σωστά;

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

Βρόχος με μετρητή για in:

Κύκλος για μεσαείναι ένας βρόχος με μετρητή. Το μπλοκ κώδικα που βρίσκεται στο σώμα του βρόχου επαναλαμβάνεται όσες φορές υπάρχουν τιμές στη λίστα του τελεστή for in, ενώ σε κάθε επανάληψη η μεταβλητή μετρητή (εδώ ονομάζεται var, αλλά φυσικά μπορείτε πείτε το όπως θέλετε) έχει την τιμή του επόμενου στοιχείου της λίστας.
Εάν η λέξη-κλειδί do βρίσκεται στην ίδια γραμμή με τη λέξη για, τότε μετά τη λίστα των ορισμάτων (πριν από το κάνω) πρέπει να βάλετε ένα ερωτηματικό.
Κάθε ένα από τα στοιχεία<список>μπορεί να περιέχει πολλά ορίσματα. Αυτό είναι χρήσιμο κατά την επεξεργασία ομάδων παραμέτρων. Σε αυτήν την περίπτωση, για να επιβάλετε την ανάλυση καθενός από τα ορίσματα στο<списке>, πρέπει να χρησιμοποιήσετε τη δήλωση set
Μπορείτε να χρησιμοποιήσετε μια μεταβλητή ως λίστα σε έναν βρόχο for.
ΣΕ<списке>για βρόχους, μπορούν να χρησιμοποιηθούν ονόματα αρχείων, τα οποία με τη σειρά τους μπορούν να περιέχουν χαρακτήρες μπαλαντέρ. Αυτό μπορεί να είναι πολύ χρήσιμο όταν εργάζεστε με μεγάλο αριθμό αρχείων.
Αν<список>δεν καθορίζεται στον βρόχο for, τότε η μεταβλητή χρησιμοποιείται ως αυτή [email προστατευμένο]- λίστα ορισμάτων γραμμής εντολών.
Κατά τη δημιουργία μιας λίστας ορισμάτων, η αντικατάσταση εντολών μπορεί να χρησιμοποιηθεί στον βρόχο for.
Η έξοδος του βρόχου μπορεί να ανακατευθυνθεί από το stdout σε ένα αρχείο ή κάπου αλλού (μπορείτε να μάθετε περισσότερα σχετικά με αυτό αναλύοντας την ανακατεύθυνση I/O).

Σύνταξη:
για var in<список>
κάνω
<выполняемые команды>
Έγινε

Παράδειγμα:
για ονόματα στο όνομα1 όνομα2 όνομα3 όνομα4
κάνω
echo $names
Έγινε

Δήλωση βρόχου Γιαέχει έναν άλλο τρόπο γραφής - πολύ παρόμοιο με τη σύνταξη του τελεστή for στη γλώσσα C. Σε αυτήν την περίπτωση, κατά την προετοιμασία των μετρητών, ορίζονται οι αρχικές τιμές των μεταβλητών ή μιας μεταβλητής και μετά από κάθε πέρασμα του βρόχος η συνθήκη ελέγχεται, εάν ο έλεγχος επιστρέψει true, τότε ξεκινά το επόμενο πέρασμα του βρόχου. Στο μπλοκ<приращение счётчиков>η τιμή των μετρητών της μεταβλητής μας πρέπει απαραίτητα να αλλάξει (όχι απαραίτητα προς τα πάνω), έτσι ώστε κατά τον έλεγχο της συνθήκης, αργά ή γρήγορα να λάβουμε την τιμή των ψεμάτων, διαφορετικά ο βρόχος δεν θα τελειώσει ποτέ. Μια πολύ βολική και το πιο σημαντικό γνώριμη επιλογή, εάν οποιαδήποτε λειτουργία χρειάζεται να επαναληφθεί καθορισμένο αριθμό φορές.

Με παρόμοια σύνταξη:
Για ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
κάνω
<выполняемые команды>
Έγινε

Παράδειγμα:
για ((var=1; var<= LIMIT ; var++))
κάνω
echo $var
Έγινε

βρόχος while:

Αυτή είναι μια αρκετά απλή κατασκευή που ελέγχει την κατάσταση πίσω από τον χειριστή ενώκαι αν αυτή η συνθήκη είναι αληθής, εκτελεί το μπλοκ εντολών που βρίσκεται μεταξύ των λέξεων do και done και στη συνέχεια προχωρά ξανά στον έλεγχο της συνθήκης. Εάν ο έλεγχος επιστρέψει false, τότε ο βρόχος τελειώνει και εκτελούνται οι ακόλουθες εντολές: Έγινε. Είναι απαραίτητο να διασφαλιστεί ότι<проверка условия>εξαρτάται από τον κώδικα που τρέχει στον βρόχο διαφορετικά, εάν το αποτέλεσμα του ελέγχου δεν αλλάξει, θα λάβετε έναν άπειρο βρόχο.
Η τυπική είσοδος, για λίγο βρόχο, μπορεί να ανακατευθυνθεί σε ένα αρχείο χρησιμοποιώντας την εντολή ανακατεύθυνσης< в конце цикла.

Σύνταξη:
ενώ<Проверка условия>
κάνω
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
Έγινε

Παράδειγμα:
ενώ [ $var0 -eq 100 ]
κάνω
echo $var
var++
Έγινε

Χειριστής ενώμπορεί να έχει πολλαπλές προϋποθέσεις. Αλλά μόνο το τελευταίο από αυτά καθορίζει τη δυνατότητα συνέχισης του κύκλου. Σε αυτήν την περίπτωση, η σύνταξη της δήλωσης βρόχου θα είναι διαφορετική από τη συνηθισμένη.
Σύνταξη(Επαναλαμβάνω για άλλη μια φορά ότι μόνο η τελευταία συνθήκη επηρεάζει την εκτέλεση του βρόχου) :
ενώ
<условие1>
<условие2>

<условиеN>
κάνω
<выполняемые команды - тело цикла>
Έγινε

μέχρι βρόχου:

Χειριστής μέχριπολύ παρόμοιο με το while, αξιολογεί επίσης τη συνθήκη, αλλά εκτελεί το σώμα του βρόχου εάν το αποτέλεσμα του υπολογισμού είναι ψευδές. Μπορεί να φαίνεται περίεργο, αλλά μέχρι να αξιολογήσει τη συνθήκη πριν από την πρώτη επανάληψη του βρόχου, όπως ενώ, και όχι μετά από αυτήν. Όπως και με τους βρόχους for/in, όταν τοποθετείτε τη λέξη-κλειδί do στην ίδια γραμμή με τη δήλωση βρόχου, πρέπει να εισαγάγετε τον χαρακτήρα ";" πριν κάνουμε.
Όπως και στην προηγούμενη περίπτωση, είναι σημαντικό να θυμάστε ότι η συνθήκη πρέπει να εξαρτάται από τις λειτουργίες στο σώμα του βρόχου, διαφορετικά το σενάριό μας δεν θα τελειώσει ποτέ.

Σύνταξη:
μέχρι<Проверка условия>
κάνω
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
Έγινε

Παράδειγμα:
μέχρι [ $var0 -gt 100] # Η συνθήκη ελέγχεται στην αρχή της επανάληψης.
κάνω
echo $var
var--
Έγινε

Μάλλον αρκετά προς το παρόν. :)

  • Πίσω
  • Προς τα εμπρός

Νέα άρθρα:

  • Η ανακάλυψη δικτύου δεν ενεργοποιείται στα Windows 7/8/2008/2012
  • Σφάλμα: Αυτή η εφαρμογή απέτυχε να ξεκινήσει επειδή δεν μπόρεσε να βρει ή να φορτώσει τα "παράθυρα" της προσθήκης πλατφόρμας Qt.
  • Διαμόρφωση αυτόματης επανεκκίνησης διαδικασιών εργασίας διακομιστής rphost.exe 1C 8.3
  • Πώς να μειώσετε το μέγεθος του αρχείου καταγραφής συναλλαγών (.ldf) στο MS SQL 2008/20012

    Το MS SQL, όπως κάθε αξιοπρεπές βιομηχανικό DBMS, μαζί με τη βάση δεδομένων, διατηρεί αρχεία καταγραφής συναλλαγών που σας επιτρέπουν να επαναφέρετε την κατάσταση ...

5

Το σενάριό σας είναι κωδικοποιημένο με επικίνδυνο τρόπο.

Πρώτον, υποθέτω ότι χρησιμοποιείτε το κέλυφος του Bash αφού το σημειώσατε με "/bash" και "/for".

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

1) Μην χρησιμοποιείτε ποτέ Αντικατάσταση εντολών, έξω ήευγενικό, χωρίς εισαγωγικά. Υπάρχει ένα μεγάλο πρόβλημα εδώ: η χρήση μιας επέκτασης χωρίς εισαγωγικά για να χωριστεί η έξοδος σε ορίσματα.

Για να είμαστε συγκεκριμένοι, αυτό το έργο $(find$ DIRWORK -type d -name) και το $(find$ DIR -type f) θα υποβληθούν σε διαχωρισμό λέξεων , επομένως, εάν το find βρει ένα αρχείο με κενά στο όνομά του, π.χ. τη λέξη "filename" διαχωρίζοντας το Το αποτέλεσμα του Bash θα περάσει 2 ορίσματα στην εντολή for για επανάληψη, δηλαδή ένα για "αρχείο" και ένα για "όνομα". Σε αυτήν την περίπτωση, θέλετε να ελπίζετε ότι θα λάβετε "αρχείο: δεν υπάρχει τέτοιο αρχείο ή κατάλογος" και "όνομα: δεν υπάρχει τέτοιο αρχείο ή κατάλογος" αντί να τα καταστρέψετε εάν υπάρχουν.

2) Κατά σύμβαση, οι μεταβλητές περιβάλλοντος (PATH, EDITOR, SHELL, ...) και οι μεταβλητές εσωτερικού φλοιού (BASH_VERSION, RANDOM, ...) χρησιμοποιούνται πλήρως. Όλα τα άλλα ονόματα μεταβλητών πρέπει να είναι πεζά. Δεδομένου ότι τα ονόματα των μεταβλητών κάνουν διάκριση πεζών-κεφαλαίων, αυτή η σύμβαση αποφεύγει τον τυχαίο επαναπροσδιορισμό των περιβαλλοντικών και εσωτερικών μεταβλητών.

Αυτή είναι μια ασφαλέστερη έκδοση του σεναρίου σας που σας προτείνω να χρησιμοποιήσετε αντ' αυτού:

My_home="/root/mydir" my_dir=" $my_home/var" dir_work="$ my_home/Local" ενώ το IFS= read -r -d "" f; κάντε # Υποθέτω ότι θέλετε επίσης να αγνοήσετε το stderr; # από ​​εδώ προήλθε το 2>&1. εάν lsof -n "$f" | grep "" > /dev/null 2> τότε επαναλάβετε "hey , "Είμαι πιο ασφαλής τώρα!" fi τελειώσει< <(find "$ dir_work" -type f -print0) while IFS= read -r -d "" f; do echo "2" done < <(find "$dir_work" -type d -name "work" -print0)

Όπως μπορείτε να δείτε, η μεταβλητή IFS έχει ρυθμιστεί σε άδεια, εμποδίζοντας έτσι την ανάγνωση από το να περικόψει τα κενά προπορευομένων και τελικών διαστημάτων από τη συμβολοσειρά. η εντολή read χρησιμοποιεί την κενή συμβολοσειρά (-d "") ως οριοθέτη για ανάγνωση μέχρι να φτάσει στο \ 0. Η εύρεση πρέπει να είναι m αντίστοιχα, επομένως χρησιμοποιεί την επιλογή -print0 για να οριοθετήσει τα δεδομένα της με \ 0 αντί για νέα γραμμή, που είναι , παραδόξως και κακόβουλα, μπορεί να είναι μέρος του ονόματος αρχείου. Ο διαχωρισμός ενός τέτοιου αρχείου σε \n σε δύο μέρη θα σπάσει τον κώδικά μας.

Η προηγούμενη απάντηση, η οποία αναφέρει ότι βρείτε ... | ενώ διάβασε το όνομα? κάνω ...; done θα πρέπει να χρησιμοποιείται για την ανάγνωση εύρεση s η έξοδος μπορεί να είναι επίσης κακή. Ο βρόχος while εκτελείται σε ένα νέο υποκέλυφος με το αντίγραφο των μεταβλητών να έχει αντιγραφεί από το γονικό. Αυτό το αντίγραφο χρησιμοποιείται στη συνέχεια για ό,τι θέλετε. Όταν ολοκληρωθεί ο βρόχος while, το αντίγραφο του υποκελύφους θα απορριφθεί και οι αρχικές μεταβλητές του γονέα δεν θα αλλάξουν.

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

0

"Μην χρησιμοποιείτε ποτέ την Αντικατάσταση εντολών, οποιουδήποτε είδους, χωρίς εισαγωγικά." Απλώς γίνεται nitpicking, αλλά είναι δυνατή η χρήση αντικατάστασης εντολών χωρίς εισαγωγικά όταν ορίζετε μια μεταβλητή: "something = $(όνομα βάσης" όνομα αρχείου με κενά ")". - Σμιθ Τζον 22 Απρ. 13 22-04-2013 21:43:10

2

Για i στο $(find$ DIRWORK -type d -name work); ηχώ "2" έγινε

θα είναι ο πρώτος που θα εκτελέσει αυτή τη γραμμή

Βρείτε την εργασία $DIRWORK -type d -name

περιμένετε μέχρι να ολοκληρωθεί η εκτέλεση της εύρεσης και, στη συνέχεια, πάρτε την έξοδο και βάλτε την ξανά στον βρόχο for

Για το i στην έξοδο του find? ηχώ "2" έγινε

μόνο τότε θα αρχίσει να εκτελείται ο βρόχος for.

Επομένως, εάν η εύρεση παίρνει πολύ χρόνο για να ολοκληρωθεί ο βρόχος for, πρέπει να περιμένει πολύ για να ξεκινήσει.

Δοκιμάστε τις προσωρινές εντολές εύρεσης διαδραστικά

$ χρόνος εύρεση $DIRWORK -τύπος d -όνομα εργασίας

και να δεις πόσο καιρό θα πάρει.

Σημειώστε επίσης ότι δεν πρέπει να χρησιμοποιείτε βρόχο for για επανάληψη πάνω από ονόματα αρχείων. Χρησιμοποιήστε έναν βρόχο while με το read , όπως αυτό:

Εύρεση$ DIRWORK -τύπος d -όνομα εργασίας | ενώ διαβάστε το όνομα? ηχώ "2" έγινε

Μπόνους: εκτελεί τον βρόχο while παράλληλα με το find . Αυτό σημαίνει ότι ο βρόχος while θα εκτελέσει μία επανάληψη μόλις το find εκτυπώσει μία γραμμή. Δεν χρειάζεται να περιμένετε την εύρεση για να ολοκληρωθεί η εκτέλεση.

mob_info