Ο Οδηγός για αρχάριους για το Shell Scripting 2 For Loops
Αν θέλετε να δημιουργήσετε το geek σας, πιστέψτε μας, ενώστε μας για τη δεύτερη δόση στη σειρά script shell. Έχουμε μερικές διορθώσεις, μερικές βελτιώσεις στο σενάριο της περασμένης εβδομάδας, και έναν οδηγό για το looping για τους απροσδιόριστους.
Το αναθεωρημένο Script του datecp
Στην πρώτη δόση του οδηγού scripting κελύφους μας, δημιουργήσαμε μια δέσμη ενεργειών που αντιγράψαμε ένα αρχείο σε ένα backup directory μετά την προσθήκη της ημερομηνίας στο τέλος του ονόματος αρχείου.
Ο Samuel Dionne-Riel επεσήμανε στα σχόλια ότι υπάρχει ένας πολύ καλύτερος τρόπος να χειριστούμε τις μεταβλητές αναφορές μας.
Τα επιχειρήματα είναι διαχωρισμένα χωριστά στο κέλυφος bash, θα συμβολιστούν όταν υπάρχει χώρος στην εκτεταμένη εντολή που προέκυψε. Στο σενάριό σου,
cp $ 1 $ 2. $ date_formatted
θα λειτουργήσει όπως προβλέπεται, εφόσον οι διευρυμένες μεταβλητές δεν έχουν κενά μέσα τους. Αν καλέσετε το σενάριο σας με αυτόν τον τρόπο:datecp "το παλιό μου όνομα" "το νέο μου όνομα"
η επέκταση θα έχει ως αποτέλεσμα αυτή την εντολή:cp νέο όνομα μου το παλιό name.the_date
πράγμα που έχει 6 επιχειρήματα.Για να αντιμετωπίσει σωστά αυτό το ζήτημα, η τελευταία γραμμή του σεναρίου πρέπει να είναι:
cp "$ 1" "$ 2. $ date_formatted"
Όπως μπορείτε να δείτε, αλλάξτε τη γραμμή της γραφής μας από:
cp -iv $ 1 $ 2. $ date_formatted
προς το:
cp -iv "$ 1" "$ 2". $ date_formatted
θα αντιμετωπίσει αυτό το πρόβλημα κατά τη χρήση της δέσμης ενεργειών σε αρχεία που έχουν κενά στο όνομα. Ο Samuel επισημαίνει επίσης ότι όταν αντιγράφετε και επικολλάτε κώδικα από αυτόν τον ιστότοπο (ή το Διαδίκτυο γενικά), φροντίστε να αντικαταστήσετε τις κατάλληλες παύλες και εισαγωγικά για τις "τυπογραφικά καλύτερες" εκείνες που συχνά τις αντικαθιστούν. Θα κάνουμε επίσης περισσότερα για να βεβαιωθούμε ότι ο κώδικας μας είναι πιο φιλικός προς την αντιγραφή / επικόλληση. ;-)
Ένας άλλος σχολιαστής, Myles Braithwaite, αποφάσισε να επεκτείνει το σενάριό μας έτσι ώστε η ημερομηνία να εμφανιστεί πριν από την επέκταση του αρχείου. Έτσι αντί για
tasteyfile.mp3.07_14_11-12.34.56
θα είχαμε αυτό:
tasteyfile.07_14_11-12.34.56.mp3
το οποίο καταλήγει να είναι λίγο πιο βολικό για τους περισσότερους χρήστες. Ο κώδικας του είναι διαθέσιμος στη σελίδα του GitHub. Ας ρίξουμε μια ματιά σε αυτό που χρησιμοποιεί για να διαχωρίσει το όνομα αρχείου.
date_formatted = $ (ημερομηνία +% Y-% m-% d_% H.% M% S)
file_extension = $ (echo "$ 1" | awk -F. 'print $ NF')
όνομα_αρχείου = $ (βασική τιμή $ 1. $ file_extension)cp -iv $ 1 $ όνομα_αρχείου- $ date_formatted. $ file_extension
Έχω αλλάξει λίγο τη μορφοποίηση, αλλά μπορείτε να δείτε ότι ο Myles δηλώνει τη λειτουργία της ημερομηνίας στη Γραμμή 1. Στη Γραμμή 2, ωστόσο, χρησιμοποιεί την εντολή "echo" με το πρώτο όρισμα του σεναρίου για να εξάγει το όνομα του αρχείου. Χρησιμοποιεί την εντολή σωλήνα για να πάρει αυτή την έξοδο και να την χρησιμοποιήσει ως είσοδο για το επόμενο μέρος. Μετά το σωλήνα, ο Myles καλεί την εντολή "awk", η οποία είναι ένα ισχυρό πρόγραμμα σάρωσης προτύπων. Χρησιμοποιώντας τη σημαία -F, λέει στην εντολή ότι ο επόμενος χαρακτήρας (μετά από ένα κενό διάστημα) είναι ο ορισμός του "διαχωριστή πεδίου". Στην περίπτωση αυτή, αυτό είναι μια περίοδος.
Τώρα, awk δείτε ένα αρχείο με το όνομα "tastyfile.mp3" ως αποτελείται από δύο πεδία: "tasteyfile" και "mp3". Τέλος, χρησιμοποιεί
'print $ NF'
για να εμφανιστεί το τελευταίο πεδίο. Σε περίπτωση που το αρχείο σας έχει πολλαπλές χρονικές περιόδους - επομένως, κάνοντας awk να δείτε πολλαπλά πεδία - θα εμφανίσει μόνο την τελευταία, η οποία είναι η επέκταση αρχείου.
Στη Γραμμή 3, δημιουργεί μια νέα μεταβλητή για το όνομα του αρχείου και χρησιμοποιεί την εντολή "basename" για να αναφέρει τα πάντα σε $ 1 εκτός την επέκταση αρχείου. Αυτό γίνεται με τη χρήση basename και δίνοντας το $ 1 ως επιχείρησή του, προσθέτοντας ένα διάστημα και την επέκταση του αρχείου. Η επέκταση αρχείου προστίθεται αυτόματα λόγω της μεταβλητής που αναφέρει τη Γραμμή 2. Τι θα έκανε αυτό
tasteyfile.mp3
και να το μετατρέψει σε
νόστιμο αρχείο
Στη συνέχεια, στην τελευταία γραμμή, οι Myles έβαλαν μαζί την εντολή που θα εξάγει τα πάντα στη σειρά. Σημειώστε ότι δεν υπάρχει αναφορά σε $ 2, ένα δεύτερο όρισμα για το σενάριο. Αυτό το συγκεκριμένο σενάριο θα αντιγράψει το εν λόγω αρχείο στον τρέχοντα κατάλογο σας αντί. Μεγάλη δουλειά Σαμουήλ και Μύες!
Εκτέλεση Scripts και $ PATH
Αναφέρουμε επίσης στο άρθρο μας για τα Βασικά στοιχεία ότι τα σενάρια δεν επιτρέπεται να αναφέρονται ως εντολές από προεπιλογή. Δηλαδή, πρέπει να δείξετε τη διαδρομή του σεναρίου για να το εκτελέσετε:
./γραφή
~ / bin / script
Αλλά, τοποθετώντας τα σενάρια σας στο ~ / bin /, θα μπορούσατε απλά να πληκτρολογήσετε τα ονόματά τους από οπουδήποτε για να τα εκτελέσετε.
Οι Commenters αφιέρωσαν αρκετό χρόνο στη συζήτηση σχετικά με το πόσο σωστό ήταν αυτό, καθώς καμία σύγχρονη διανομή Linux δεν δημιουργεί αυτόν τον κατάλογο από προεπιλογή. Επιπλέον, κανένας δεν το προσθέτει στη μεταβλητή $ PATH από προεπιλογή, το οποίο είναι αυτό που απαιτείται για να εκτελεστούν τα σενάρια σαν εντολές. Ήμουν λίγο αμήχανα γιατί αφού έλεγξα τη μεταβλητή μου $ PATH, οι commenters ήταν σωστοί, αλλά η κλήση σεναρίων εξακολουθούσε να λειτουργεί για μένα. Έχω ανακαλύψει γιατί: πολλά σύγχρονα Linux distros δημιουργούν ένα ειδικό αρχείο στον οικείο κατάλογο του χρήστη - .profile.
Αυτό το αρχείο διαβάζεται από το bash (εκτός αν υπάρχει .bash_profile στον οικείο κατάλογο του χρήστη) και στο κάτω μέρος υπάρχει μια ενότητα που προσθέτει το φάκελο ~ / bin / στη μεταβλητή $ PATH, αν υπάρχει. Έτσι, αυτό το μυστήριο ξεκαθαρίζεται. Για την υπόλοιπη σειρά, θα συνεχίσω να τοποθετώ σενάρια στον κατάλογο ~ / bin / επειδή είναι scripts χρηστών και θα πρέπει να μπορούν να εκτελούνται από χρήστες. Και, φαίνεται ότι δεν χρειάζεται πραγματικά να χάλια με τη μεταβλητή $ PATH με το χέρι για να δουλέψουμε τα πράγματα.
Επαναλαμβανόμενες εντολές με βρόχους
Ας φτάσουμε σε ένα από τα πιο χρήσιμα εργαλεία στο οπλοστάσιο για την αντιμετώπιση επαναλαμβανόμενων εργασιών: βρόχους. Σήμερα, θα συζητήσουμε βρόχους "για".
Το βασικό περίγραμμα ενός for-loop έχει ως εξής:
για ΜΕΤΑΒΛΗΤΟ στο ΚΑΤΑΛΟΓΟ. κάνω
command1
command2
...
commandn
Έγινε
Η μεταβλητή μπορεί να είναι οποιαδήποτε μεταβλητή, αν και συνήθως χρησιμοποιείται το μικρό πεζά "i". Ο κατάλογος είναι ένας κατάλογος στοιχείων. μπορείτε να ορίσετε πολλά στοιχεία (διαχωρίζοντάς τα με ένα κενό), να υποδείξετε ένα εξωτερικό αρχείο κειμένου ή να χρησιμοποιήσετε έναν αστερίσκο (*) για να υποδηλώσετε οποιοδήποτε αρχείο στον τρέχοντα κατάλογο. Οι εντολές που εμφανίζονται είναι χαραγμένες με σύμβαση, επομένως είναι ευκολότερο να δείτε τη φωλιά - βάζοντας βρόχους σε βρόχους (έτσι μπορείτε να βγείτε ενώ βγάζετε βρόχο).
Επειδή οι λίστες χρησιμοποιούν διαστήματα ως οριοθέτες - δηλαδή, ένας χώρος σημαίνει μετακίνηση στο επόμενο στοιχείο της λίστας - τα αρχεία που έχουν κενά στο όνομα δεν είναι πολύ φιλικά. Προς το παρόν, ας δούμε να δουλεύουμε με αρχεία χωρίς spaces.Let ξεκινήστε με ένα απλό script για να εμφανίσετε τα ονόματα των αρχείων στον τρέχοντα κατάλογο. Δημιουργήστε ένα νέο σενάριο στον φάκελο ~ / bin / με τίτλο "loopscript". Εάν δεν θυμάστε πώς να το κάνετε αυτό (συμπεριλαμβανομένου του χαρακτηρισμού ως εκτελέσιμου και προσθέτοντας το hack bang hack), ανατρέξτε στο άρθρο bash scripting basics.
Σε αυτό, πληκτρολογήστε τον ακόλουθο κώδικα:
για το i στο στοιχείο 1 στοιχείο 2 στοιχείο 3 στοιχείο 4 στοιχείο 5 στοιχείο 6; κάνω
echo "$ i"
Έγινε
Όταν εκτελείτε το σενάριο, θα πρέπει να λάβετε αυτά τα στοιχεία λίστας ως έξοδο.
Πολύ απλό, έτσι; Ας δούμε τι συμβαίνει αν αλλάξουμε λίγο τα πράγματα. Αλλάξτε το σενάριο σας έτσι λέει αυτό:
για το i στο *; κάνω
echo "$ i"
Έγινε
Όταν εκτελείτε αυτήν τη δέσμη ενεργειών σε ένα φάκελο, θα πρέπει να λάβετε μια λίστα αρχείων που περιέχει ως έξοδο.
Τώρα, ας αλλάξουμε την εντολή echo σε κάτι πιο χρήσιμο - ας πούμε, την εντολή zip. Δηλαδή, θα προσθέσουμε αρχεία σε ένα αρχείο. Και, ας πάρουμε κάποια επιχειρήματα στο μίγμα!
για το i στο $ @; κάνω
zip αρχείο "$ i"
Έγινε
Υπάρχει κάτι νέο! "$ @" Είναι μια συντόμευση για "$ 1 $ 2 $ 3 ... $ n". Με άλλα λόγια, είναι ο πλήρης κατάλογος όλων των επιχειρημάτων που έχετε ορίσει. Τώρα, προσέξτε τι συμβαίνει όταν τρέχω το σενάριο με πολλά αρχεία εισόδου.
Μπορείτε να δείτε ποια αρχεία βρίσκονται στο φάκελο μου. Έτρεξα την εντολή με έξι επιχειρήματα και κάθε αρχείο προστέθηκε σε ένα αρχειοθήκη με αρχεία με όνομα "archive.zip". Εύκολο, σωστά?
Για τους βρόχους είναι πολύ υπέροχο. Τώρα μπορείτε να εκτελέσετε λειτουργίες παρτίδας σε λίστες αρχείων. Για παράδειγμα, μπορείτε να αντιγράψετε όλα τα επιχειρήματα του σεναρίου σας σε ένα αρχειοθετημένο αρχείο, να μετακινήσετε τα πρωτότυπα σε διαφορετικό φάκελο και να εξασφαλίσετε αυτόματα την αντιγραφή αυτού του αρχείου zip σε έναν απομακρυσμένο υπολογιστή. Αν ρυθμίσετε αρχεία κλειδιού με SSH, δεν θα χρειαστεί καν να εισαγάγετε τον κωδικό πρόσβασής σας και μπορείτε ακόμη και να πείτε στο σενάριο να διαγράψει το αρχείο zip μετά τη μεταφόρτωσή του!
Η χρήση για βρόχους καθιστά εύκολη την πραγματοποίηση μιας δέσμης ενεργειών για όλα τα αρχεία σε έναν κατάλογο. Μπορείτε να στοιβάζετε μια μεγάλη ποικιλία εντολών μαζί και να χρησιμοποιήσετε πολύ εύκολα τα επιχειρήματα για να δημιουργήσετε και να πετάξετε τον κατάλογο, και αυτό είναι μόνο η κορυφή του παγόβουνου.
Bash scripters, έχετε κάποιες προτάσεις; Έχετε κάνει ένα χρήσιμο σενάριο που χρησιμοποιεί βρόχους; Θέλετε να μοιραστείτε τις σκέψεις σας σχετικά με τη σειρά; Αφήστε μερικά σχόλια και βοηθήστε άλλους αρχάριους scripting έξω!