Loop bash dengan contoh

- 897
- 33
- Hector Kuhic
Siap menyelam ke looping bash? Dengan popularitas Linux sebagai sistem operasi gratis, dan dipersenjatai dengan kekuatan antarmuka baris perintah bash, seseorang dapat melangkah lebih jauh, mengkode loop canggih langsung dari baris perintah, atau dalam skrip bash bash.
Memanfaatkan kekuatan ini, seseorang dapat memanipulasi dokumen apa pun, setiap set file, atau mengimplementasikan algoritma canggih dari hampir semua jenis dan rasa. Anda tidak mungkin mengalami batasan apa pun jika Anda menggunakan bash sebagai dasar untuk skrip Anda, dan loop bash membentuk bagian yang kuat dari ini.
Yang mengatakan, loop bash terkadang bisa rumit dalam hal sintaksis dan pengetahuan di sekitarnya adalah yang terpenting. Hari ini kami memberi Anda satu set contoh loop bash untuk membantu Anda meningkatkan dengan cepat dan menjadi mahir! Ayo Memulai!
Dalam tutorial ini Anda akan belajar:
- BAGAIMANA BASH
untuk
,ketika
Dansampai
Loop berbasis bekerja, dengan contoh - Bagaimana Bash Membutuhkan Pengakhiran Pernyataan Loop-Startting sebelum bagian ... yang dilakukan dari loop dapat mengikuti, dan bagaimana hal ini berhubungan dengan IF dan pernyataan lainnya
- Cara menerapkan loop bash dasar dan menengah
- Bagaimana Subsklells Bekerja Dan Bagaimana Mereka Dapat Digunakan Di Dalam Deklarasi Lingkaran Bash
- Cara memulai pengkodean loop secara defensif, menghindari kesalahan dalam output
- Bagaimana kode
One-Liners
(istilah umum yang digunakan di antara pengembang bash) pada baris perintah versus mengimplementasikan kode yang sama dalam skrip bash - Bagaimana
;
Idiom sintaks adalah masalah penting dalam hal pengkodean loop bash, baik pada baris perintah maupun dalam skrip

Contoh loop bash
- Mari kita mulai dengan dasar
untuk
lingkaran:
Menyalin$ untuk saya dalam $ (SEQ 1 5); lakukan gema $ i; selesai 1 2 3 4 5
Seperti yang Anda lihat, dasar
untuk
loop dalam bash relatif mudah diterapkan. Inilah langkah -langkahnya:untuk: Menunjukkan kami ingin memulai loop berbasis baru
Saya: Variabel yang akan kami gunakan untuk menyimpan nilai yang dihasilkan oleh klausa di dalamdi dalam
kata kunci (yaitu urutan tepat di bawah)
$ (SEQ 1 5): Ini mengeksekusi perintah di dalam sub-shell lain.Untuk memahami cara kerjanya, pertimbangkan contoh ini:
Menyalin$ seq 1 5 1 2 3 4 5
Pada dasarnya,
$ ()
Sintaks dapat digunakan kapan saja (dan di mana saja!) Anda ingin memulai subshell baru. Ini adalah salah satu fitur paling kuat dari shell bash. Pertimbangkan misalnya:
MenyalinTes $ Cat.txt 1 2 $ echo "$ (tes kucing.txt | head -n1) "1
Seperti yang Anda lihat, di sini subshell yang dieksekusi 'tes kucing.txt | head -n1 '(' head -n1 'memilih hanya baris pertama) dan kemudian menggemakan output dari subshell itu.
Mari kita lanjutkan menganalisis loop kami di atas:
;: Ini sangat penting. Dalam Bash, "tindakan" apa pun, seperti misalnya A 'untuk' Loop Start, atau tes pernyataan 'jika', atau loop sementara dll. perlu diakhiri dengan ';'. Jadi, ';' di sini * sebelum * lakukan, bukan setelahnya. Pertimbangkan contoh jika sangat mirip:
Menyalin$ if ["a" == "a"]; Lalu echo "Ya!"; fi ya!
Perhatikan bagaimana lagi
;
ada sebelumKemudian
, tidak setelah. Tolong jangan biarkan ini membingungkan Anda saat skrip untuk atau saat loop, jika pernyataan dll. Ingatlah bahwa setiap tindakan perlu diakhiri sebelum tindakan baru, dan dengan demikianuntuk
ataujika
perlu diakhiri sebelum tindakan berikutnya yang 'lalu' dalam contoh pernyataan if, danMengerjakan
di loop untuk di atas!Akhirnya, kami memiliki:
Mengerjakan: Menunjukkan itu
untuk
apa yang terjadi sebelumnya… Mengerjakan…
Apa yang terjadi selanjutnya. Perhatikan sekali lagi bahwa kata tindakan ini setelah penutupan;
digunakan untuk menutup pernyataan pembukaan loop.
echo $ i: Di sini kami mengeluarkan nilai yang disimpan ke dalamSaya
variabel ($ i
)
;: Menghentikan pernyataan gema (mengakhiri setiap tindakan)
Selesai: Menunjukkan bahwa ini adalah akhir dari loop kami - Mari kita ambil contoh yang sama ini tetapi tulislah secara berbeda:
Menyalin$ untuk saya dalam 1 2 3 4 5; lakukan gema $ i; selesai 1 2 3 4 5
Anda dapat melihat sekarang bagaimana ini berhubungan dengan contoh di atas; Ini adalah komentar yang sama, meskipun di sini kami tidak menggunakan subshell untuk menghasilkan urutan input untuk kami, kami secara manual menentukannya sendiri.
Apakah ini membuat kepala Anda tidak bisa berlomba tentang kemungkinan penggunaan sedikit? Jadi harus 🙂 Mari kita lakukan sesuatu yang keren dengan ini sekarang.
- Meningkatkan kompleksitas loop kami untuk memasukkan file:
Menyalin$ ls 1.txt 2.txt 3.txt 4.txt 5.txt
Menyalin$ head -n1 *.txt ==> 1.txt <== 1 ==> 2.txt <== 1 ==> 3.txt <== 1 ==> 4.txt <== 1 ==> 5.txt <== 1
Menyalin$ for I in $ (ls *.txt); lakukan kucing "$ i" | head -n1; selesai 1 1 1 1 1
Bisakah Anda mencari tahu apa yang terjadi di sini? Melihat bagian baru ini untuk lingkaran, kita lihat:
$ (ls *.txt): Ini akan mencantumkan semua file txt di direktori saat ini, dan perhatikan bahwa nama file tersebut akan disimpan diSaya
variabel, satu file per/untuk setiap loopuntuk
Loop akan berjalan.Dengan kata lain, pertama kali loop (bagian antara dilakukan dan dilakukan) terjadi,
$ i
akan berisi1.txt
. Lari berikutnya$ i
akan berisi2.txt
dan seterusnya.kucing "$ i" | head -n1: Di sini kita mengambil
$ i
variabel (seperti yang telah kita lihat ini akan terjadi1.txt
, diikuti oleh2.txt
dll.) dan kucing file itu (menampilkannya) dan mengambil baris pertama yang samahead -n1
. Jadi, 5 kali1
adalah output, karena itu adalah baris pertama di semua 5 file seperti yang dapat kita lihat dari sebelumnyahead -n1
di semua .file txt. - Bagaimana dengan yang sangat kompleks sekarang?
Menyalin$ tail -n1 *.txt ==> 1.txt <== 1 ==> 2.txt <== 2 ==> 3.txt <== 3 ==> 4.txt <== 4 ==> 5.txt <== 5
Menyalin$ for I in $ (ls *.txt 2>/dev/null); do echo -n "$ (tail -n1 $ i)"; echo "dari $ i !"; selesai 1 dari 1.txt ! 2 dari 2.txt ! 3 dari 3.txt ! 4 dari 4.txt ! 5 dari 5.txt !
Dapatkah Anda berolahraga apa yang terjadi di sini?
Mari menganalisisnya langkah demi langkah.
untuk saya masuk : Kami sudah tahu ini; Mulailah yang baru
untuk
loop, tetapkan variabel I untuk apa pun yang mengikuti didi dalam
ayat
$ (ls *.txt 2>/dev/null): Sama dengan perintah di atas; Buat daftar semua file txt, tetapi kali ini dengan sedikit perlindungan penghindaran kesalahan yang pasti. Lihat:$ untuk saya dalam $ (ls i.Mengerjakan.bukan.ada); do echo "hanya menguji tidak ada file"; selesai ls: tidak dapat mengakses 'i.Mengerjakan.bukan.ada ': tidak ada file atau direktori seperti itu
Output yang tidak terlalu profesional! Dengan demikian;
$ untuk saya dalam $ (ls i.Mengerjakan.bukan.ada 2>/dev/null); do echo "hanya menguji tidak ada file"; Selesai
Tidak ada output yang dihasilkan oleh pernyataan ini.
Mari kita lanjutkan analisis kita:
; Mengerjakan: Menghentikan Pernyataan Awal Loop, Mulailah Bagian Do… Selesai Definisi Loop Kami
echo -n "$ (tail -n1 $ i)";: Pertama,-N
berdiri untuk Jangan output trailing newline di akhir output yang diminta.Selanjutnya, kami mengambil baris terakhir dari setiap file. Perhatikan bagaimana kami telah mengoptimalkan kode kami dari atas? Saya.e. bukannya melakukan
file kucing.txt | ekor -n1
seseorang bisa melakukannyaTail -N1 file.txt
- Singkatan yang mungkin dilewatkan oleh pengembang pesta baru. Dengan kata lain, di sini kita hanya mencetak1
(baris terakhir dalam 1.txt) segera diikuti oleh2
untuk2.txt
dll.
Sebagai sidenote, jika kami tidak menentukan perintah tindak lanjut ECHO, outputnya hanya
12345
Tanpa Newline:
Menyalin$ for I in $ (ls *.txt 2>/dev/null); do echo -n "$ (tail -n1 $ i)"; selesai $ 12345
Perhatikan bagaimana bahkan Newline terakhir tidak ada, maka output sebelum prompt
$
kembali.Akhirnya kami punya
echo "dari $ i !";
(Menunjukkan kepada kamidari 1.txt !
output) dan penutupan loop olehSelesai
.Saya percaya sekarang Anda dapat melihat seberapa kuat ini, dan seberapa banyak kontrol yang dapat dikenakan atas file, konten dokumen dan banyak lagi!
Mari kita hasilkan string acak panjang dengan loop sementara berikutnya! Seru?
- Menggunakan loop sementara untuk menghasilkan string acak:
Menyalin$ Acak = "$ (tanggal +%s%n | cut -b14-19)" $ count = 0; Myrandom =; sementara benar; do count = $ [$ count + 1]; if [$ count -gt 10]; lalu hancurkan; fi; Myrandom = "$ myrandom $ (echo" $ random "| sed 's |^\ (.\).*| \ 1 | ') "; Done; echo" $ myrandom "6421761311
Itu terlihat kompleks! Mari menganalisisnya langkah demi langkah. Tapi pertama -tama, mari kita lihat bagaimana ini akan terlihat di dalam naskah bash.
- Contoh fungsionalitas yang sama, diimplementasikan di dalam skrip bash:
MenyalinTes $ Cat.SH #!/bin/bash random = "$ (tanggal +%S%n | cut -b14-19)" count = 0 myrandom = sementara benar; do count = $ [$ count + 1] jika [$ count -gt 10]; Kemudian break fi myrandom = "$ myrandom $ (echo" $ random "| sed 's |^\ (.\).*| \ 1 | ') "Done echo" $ myrandom "
$ chmod +x tes.sh $ ./tes.SH 1111211213 $ ./tes.SH 1212213213
Cukup mengejutkan pada saat-saat bahwa kode looping bash yang kompleks seperti itu dapat dengan mudah dipindahkan ke 'satu-liner' (istilah yang digunakan pengembang bash untuk merujuk pada apa realitas naskah kecil tetapi diimplementasikan langsung dari baris perintah, biasanya pada a satu baris (atau pada beberapa).
Sekarang mari kita mulai menganalisis dua contoh terakhir kita - yang sangat mirip. Perbedaan kecil dalam kode, terutama di sekitar idiom ';' dijelaskan di Contoh 7 di bawah:
Acak = "$ (tanggal +%s%n | cut -b14-19)" di baris 4: ini membutuhkan (menggunakan
CUT -B14-19
) 6 digit terakhir dari waktu zaman saat ini (jumlah detik yang telah berlalu sejak 1 Januari 1970) seperti yang dilaporkan olehtanggal +%s%n
dan menetapkan string yang dihasilkan ke variabel acak, sehingga mengatur entropi semi-acak ke kumpulan acak, secara sederhana "membuat kumpulan acak menjadi lebih acak".
Hitung = 0 di baris 6: aturMENGHITUNG
variabel ke0
Myrandom = pada baris 7: aturMyrandom
variabel untuk 'kosong' (tidak ada nilai yang ditetapkan)
Sedangkan ... lakukan… selesai Antara baris 9 dan baris 15: Ini harus jelas sekarang; Mulailah beberapa saat, jalankan kode di antara klausa yang dilakukan ...
BENAR: Dan selama pernyataan yang mengikuti 'while' dievaluasi sebagai benar, loop akan berlanjut. Di sini pernyataan itu 'benar' yang berarti bahwa ini adalah loop yang tidak terbatas, hingga amerusak
pernyataan diberikan.
Count = $ [$ count + 1] On Line 10: Tingkatkan kamiMENGHITUNG
variabel oleh1
if [$ count -gt 10]; Kemudian On Line 11: Pernyataan IF untuk memeriksa apakah variabel kami lebih besar-GT 10
, Dan jika demikian, jalankan ..fi
bagian
merusak On Line 12: Ini akan memecah tidak terbatas saat loop (i.e. KapanMENGHITUNG
lebih besar lagi10
loop akan berakhir)
Myrandom = "… di baris 14: Kami akan menetapkan nilai baruMyrandom
$ Myrandom Di baris 14: Pertama, ambil apa yang sudah kita miliki di dalam variabel ini, dengan kata lain, kita akan menambahkan sesuatu di akhir dari apa yang sudah ada, dan ini untuk setiap loop berikutnya
$ (echo "$ random" | sed 's |^\ (.\).*| \ 1 | ') pada baris 14: Ini adalah bagian yang ditambahkan setiap kali. Pada dasarnya, itu gemaACAK
variabel dan mengambil karakter pertama dari output itu menggunakan ekspresi reguler yang kompleks di SED. Anda dapat mengabaikan bagian itu jika Anda suka, pada dasarnya menyatakan "Ambil karakter pertama dari$ Acak
output variabel dan buang yang lainnya "Anda dapat melihat bagaimana output (misalnya
1111211213
) dihasilkan; satu karakter (kiri-ke-kanan) pada saat itu, menggunakan loop while, yang loop10
kali sebagai hasil dariMENGHITUNG
Pengecualian variabel penghitung.Jadi mengapa output sering dalam format
1
,2
,3
dan lebih sedikit dari angka lainnya? Ini karenaACAK
variabel mengembalikan variabel semi-acak (berdasarkan padaAcak =…
biji) yang berada di kisaran 0 hingga 32767. Dengan demikian, seringkali angka ini akan dimulai dengan 1, 2 atau 3. Misalnya 10000-19999 semuanya akan kembali1
dll. sebagai karakter pertama dari output selalu diambil oleh SED! - Skrip pendek untuk menyoroti kemungkinan untuk mengatur (atau gaya) kode looping bash dengan cara yang berbeda tanpa menggunakan
;
idiom.Kita perlu mengklarifikasi perbedaan kecil dari skrip bash versus skrip baris perintah satu kalimat.
CATATAN
Perhatikan bahwa dalam skrip bash (tes.sh) tidak banyak;
Idiom. Ini karena kita sekarang telah membagi kode melalui beberapa baris, dan a;
adalah bukan diperlukan saat ada karakter EOL (akhir garis). Karakter seperti itu (Newline atau Carriage Return) tidak terlihat di sebagian besar editor teks tetapi itu jelas jika Anda memikirkan fakta bahwa setiap perintah ada di baris yang terpisah.Perhatikan juga bahwa Anda dapat menempatkan
Mengerjakan
Klausul dariketika
Loop pada baris berikutnya juga, sehingga menjadi tidak perlu bahkan menggunakan;
di sana.
Menyalin$ Cat test2.SH #!/bin/bash for i in $ (seq 1 3) do echo "... looping ... $ i ..." selesai
$ ./test2.SH ... Looping ... 1 ... Looping ... 2 ... Looping ... 3 ..
Saya pribadi lebih suka gaya sintaks yang diberikan Contoh 6, karena tampaknya lebih jelas apa niat kode ini dengan menulis pernyataan loop secara penuh pada satu baris (sama dengan bahasa pengkodean lainnya), meskipun pendapat dan gaya sintaksis berbeda per pengembang, atau per komunitas pengembang.
- Akhirnya, mari kita lihat pesta 'sampai' loop:
Menyalin$ Nr = 0; sampai [$ nr -eq 5]; do echo "$ nr"; Nr = $ [$ nr + 1]; selesai 0 1 2 3 4
Mari kita analisis contoh ini:
Nr = 0: Di sini menetapkan variabel bernama
Nr
, ke nol
sampai: Kami memulai loop 'sampai' kami
[$ Nr -eq 5]: Ini milik kamijika
kondisi, atau lebih baiksampai
kondisi. Katakujika
Karena sintaks (dan kerja) mirip dengan perintah uji, saya.e. perintah underlaying yang digunakan dijika
pernyataan. Dalam bash, perintah uji juga dapat diwakili oleh tunggal["]
kurung. Itu$ Nr -eq 5
Tes berarti; Saat variabel kamiNr
mencapai 5, maka tes akan menjadi benar, pada gilirannya membuatsampai
loop end sebagai kondisi dicocokkan (cara lain untuk membaca ini adalah sebagai 'sampai benar' atau 'sampai variabel NR kami sama dengan 5'). Perhatikan bahwa setelah nr adalah 5, kode loop tidak lagi dieksekusi, sehingga 4 adalah angka terakhir yang ditampilkan.
;: Menghentikan pernyataan kami sampai kami, seperti yang dijelaskan di atas
Mengerjakan: Mulailah rantai tindakan kami untuk dieksekusi sampai pernyataan yang diuji menjadi benar/valid
echo "$ nr;":gema
dari nilai saat ini dari variabel kamiNr
Nr = $ [$ nr + 1];: Tingkatkan variabel kami. Itu$ ['...']
Metode perhitungan khusus untuk bash
Selesai: Menghentikan rantai tindakan/kode loop kamiSeperti yang Anda lihat, sementara dan sampai loop sangat mirip, meskipun sebenarnya mereka bertentangan. Saat loop dieksekusi selama ada sesuatu yang benar/valid, sedangkan sampai loop dieksekusi selama ada sesuatu yang 'belum valid/benar'. Seringkali mereka dapat dipertukarkan dengan membalikkan kondisi.
Kesimpulan
Saya percaya Anda bisa mulai melihat kekuatan pesta, dan terutama untuk, sementara dan sampai loop bash. Kami hanya menggaruk permukaan di sini, dan saya mungkin akan kembali nanti dengan contoh canggih lebih lanjut. Sementara itu, tinggalkan kami komentar tentang bagaimana Anda menggunakan loop bash dalam tugas atau skrip sehari-hari Anda. Menikmati!
Tutorial Linux Terkait:
- Loop bersarang dalam skrip bash
- Menguasai loop skrip bash
- Pengantar Otomatisasi Linux, Alat dan Teknik
- Hal -hal yang harus diinstal pada ubuntu 20.04
- Multi-threaded Bash Scripting & Manajemen Proses di…
- Hal -hal yang harus dilakukan setelah menginstal ubuntu 20.04 FOSSA FOSSA Linux
- Sistem Linux Hung? Cara melarikan diri ke baris perintah dan…
- Menangani input pengguna dalam skrip bash
- Mint 20: Lebih baik dari Ubuntu dan Microsoft Windows?
- Hal -hal yang harus diinstal pada Ubuntu 22.04