Gelung bash dengan contoh

Gelung bash dengan contoh

Bersedia untuk menyelam ke dalam gelung bash? Dengan populariti Linux sebagai sistem operasi percuma, dan bersenjata dengan kuasa antara muka baris perintah bash, seseorang boleh pergi lebih jauh lagi, pengekodan gelung maju dari baris arahan, atau dalam skrip bash.

Memanfaatkan kuasa ini, seseorang dapat memanipulasi sebarang dokumen, mana -mana set fail, atau melaksanakan algoritma lanjutan hampir semua jenis dan rasa. Anda tidak mungkin menghadapi sebarang batasan jika anda menggunakan bash sebagai asas untuk skrip anda, dan gelung bash membentuk bahagian yang kuat dari ini.

Yang mengatakan, gelung bash kadang -kadang boleh menjadi rumit dari segi sintaks dan pengetahuan sekitarnya adalah yang paling utama. Hari ini kami membentangkan dengan anda satu set contoh gelung bash untuk membantu anda menaikkan skil dengan cepat dan menjadi mahir gelung bash! Mari kita mulakan!

Dalam tutorial ini anda akan belajar:

  • Bagaimana bash untuk, manakala dan sehingga Gelung berasaskan berfungsi, dengan contoh
  • Bagaimana bash memerlukan penamatan pernyataan permulaan gelung sebelum bahagian ... yang dilakukan dari gelung dapat diikuti, dan bagaimana ini berkaitan dengan IF dan pernyataan lain
  • Cara melaksanakan gelung bash asas dan sederhana
  • Bagaimana subshells berfungsi dan bagaimana ia boleh digunakan di dalam deklarasi skop gelung bash
  • Cara Memulakan Gelung Pengekodan Defensif, Mengelakkan Kesalahan Dalam Output
  • Cara kod satu-liners (istilah biasa yang digunakan di kalangan pemaju bash) pada baris arahan berbanding melaksanakan kod yang sama dalam skrip bash
  • Bagaimana ; Idiom sintaks adalah perkara penting ketika datang ke pengekodan gelung bash, baik pada baris arahan dan skrip
BASH SCRIPTING - Gelung bash dengan contoh

Contoh gelung bash

  1. Mari kita mulakan dengan asas untuk Gelung:
    $ untuk i dalam $ (seq 1 5); lakukan echo $ i; dilakukan 1 2 3 4 5
    Salinan

    Seperti yang anda lihat, asas untuk gelung di bash agak mudah dilaksanakan. Berikut adalah langkah -langkah:

    untuk: Menunjukkan kita mahu memulakan gelung berasaskan baru
    i: pemboleh ubah yang akan kami gunakan untuk menyimpan nilai yang dihasilkan oleh klausa di dalamnya dalam Kata kunci (iaitu urutan di bawah)
    $ (seq 1 5): Ini melaksanakan arahan di dalam sub-shell yang lain.

    Untuk memahami bagaimana ini berfungsi, pertimbangkan contoh ini:

    $ seq 1 5 1 2 3 4 5
    Salinan

    Pada asasnya, $ () sintaks boleh digunakan setiap kali (dan di mana sahaja!) anda mahu memulakan subshell baru. Ini adalah salah satu ciri paling kuat dari kulit bash. Pertimbangkan sebagai contoh:

    Ujian CAT $.txt 1 2 $ echo "$ (ujian kucing.txt | kepala -n1) "1
    Salinan

    Seperti yang anda lihat, di sini Subshell menjalankan ujian kucing '.txt | kepala -n1 '(' kepala -n1 'hanya memilih baris pertama) dan kemudian echo'ed output subshell itu.

    Mari terus menganalisis kami untuk gelung di atas:

    ;: Ini sangat penting. Di bash, apa -apa "tindakan", seperti contoh 'untuk' gelung bermula, atau ujian pernyataan 'if', atau gelung sementara dll. perlu ditamatkan dengan ';'. Oleh itu, ';; ada di sini * sebelum * lakukan, bukan selepas itu. Pertimbangkan ini sama jika contoh:

    $ jika ["a" == "a"]; Kemudian echo "ya!"; fi ya!
    Salinan

    Perhatikan bagaimana lagi ; adalah sebelum kemudian, Tidak selepas. Jangan biarkan ini mengelirukan anda semasa skrip untuk atau semasa gelung, jika pernyataan dll. Ingatlah bahawa setiap tindakan perlu ditamatkan sebelum tindakan baru, dan dengan itu untuk atau jika perlu ditamatkan sebelum tindakan seterusnya yang 'kemudian' dalam contoh pernyataan IF, dan lakukan di gelung untuk di atas!

    Akhirnya, kita ada:

    lakukan: Menunjukkan bahawa untuk apa yang datang sebelum ini ... lakukan .. apa yang akan datang. Perhatikan lagi bahawa perkataan tindakan ini adalah selepas penutupan ; digunakan untuk menutup penyataan pembukaan gelung.
    echo $ i: Di sini kita mengeluarkan nilai yang disimpan ke dalam i berubah ($ i)
    ;: Menamatkan pernyataan echo (menamatkan setiap tindakan)
    selesai: Tunjukkan bahawa ini adalah akhir gelung kami

  2. Mari kita ambil contoh yang sama tetapi tulisnya secara berbeza:
    $ untuk saya dalam 1 2 3 4 5; lakukan echo $ i; dilakukan 1 2 3 4 5
    Salinan

    Anda dapat melihat sekarang bagaimana ini berkaitan dengan contoh di atas; Ini adalah komen yang sama, walaupun di sini kami tidak menggunakan subshell untuk menghasilkan urutan input untuk kami, kami secara manual menyatakannya sendiri.

    Adakah ini menetapkan kepala anda berlumba -lumba mengenai kemungkinan penggunaan sedikit? Oleh itu, 🙂 mari kita buat sesuatu yang sejuk dengan ini sekarang.

  3. Meningkatkan kerumitan kami untuk gelung untuk memasukkan fail:
    $ ls 1.TXT 2.TXT 3.TXT 4.TXT 5.txt
    Salinan
    $ kepala -n1 *.txt ==> 1.txt <== 1 ==> 2.txt <== 1 ==> 3.txt <== 1 ==> 4.txt <== 1 ==> 5.txt <== 1 
    Salinan
    $ untuk i dalam $ (ls *.txt); Adakah kucing "$ i" | kepala -n1; dilakukan 1 1 1 1 1
    Salinan

    Bolehkah anda menyelesaikan apa yang berlaku di sini? Melihat bahagian baru ini untuk gelung, kita lihat:
    $ (ls *.txt): Ini akan menyenaraikan semua fail TXT dalam direktori semasa, dan ambil perhatian bahawa nama fail tersebut akan disimpan di i pemboleh ubah, satu fail per/untuk setiap gelung untuk Gelung akan berjalan.

    Dalam erti kata lain, kali pertama gelung (bahagian antara lakukan dan selesai) berlaku, $ i akan mengandungi 1.txt. Larian seterusnya $ i akan mengandungi 2.txt dan sebagainya.

    Kucing "$ i" | kepala -n1: Di sini kita mengambil $ i berubah -ubah (seperti yang kita lihat ini akan berlaku 1.txt, diikuti oleh 2.txt dan lain-lain.) dan kucing yang memfailkannya (memaparkannya) dan mengambil baris pertama yang sama kepala -n1. Oleh itu, 5 kali 1 adalah output, kerana itu adalah baris pertama dalam semua 5 fail seperti yang dapat kita lihat dari sebelumnya kepala -n1 di semua .fail txt.

  4. Bagaimana dengan yang sangat kompleks sekarang?
     $ ekor -n1 *.txt ==> 1.txt <== 1 ==> 2.txt <== 2 ==> 3.txt <== 3 ==> 4.txt <== 4 ==> 5.txt <== 5 
    Salinan
    $ untuk i dalam $ (ls *.txt 2>/dev/null); lakukan echo -n "$ (ekor -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 ! 
    Salinan

    Bolehkah anda bersenam apa yang berlaku di sini?

    Mari kita menganalisisnya dengan langkah demi langkah.

    untuk saya : Kita sudah tahu ini; Mulakan yang baru untuk gelung, berikan pemboleh ubah saya kepada apa sahaja yang berikut di dalam fasal
    $ (ls *.txt 2>/dev/null): Sama seperti arahan di atas; Senaraikan semua fail TXT, tetapi kali ini dengan sedikit perlindungan menghindari kesilapan yang pasti. Melihat:

    $ untuk i dalam $ (ls i.lakukan.tidak.wujud); Adakah echo "hanya menguji tidak wujud fail"; selesai ls: tidak dapat mengakses 'i.lakukan.tidak.wujud ': tiada fail atau direktori sedemikian 

    Output tidak begitu profesional! Dengan itu;

    $ untuk i dalam $ (ls i.lakukan.tidak.wujud 2>/dev/null); Adakah echo "hanya menguji tidak wujud fail"; selesai 

    Tiada output dihasilkan oleh pernyataan ini.

    Mari teruskan analisis kami:

    ; lakukan: menamatkan pernyataan permulaan untuk gelung, mulakan bahagian ... yang dilakukan dari definisi gelung kami
    echo -n "$ (ekor -n1 $ i)";: Pertama, -n bermaksud Jangan output garis baru yang trailing pada akhir output yang diminta.

    Seterusnya, kami mengambil baris terakhir setiap fail. Perhatikan bagaimana kami telah mengoptimumkan kod kami dari atas? i.e. bukannya melakukan fail kucing.txt | ekor -n1 seseorang hanya boleh melakukannya Fail Tail -N1.txt - seorang pemaju bash baru yang mudah terlepas. Dengan kata lain, di sini kita hanya mencetak 1 (baris terakhir dalam 1.txt) segera diikuti oleh 2 untuk 2.txt dan lain-lain.



    Sebagai sidenote, jika kita tidak menentukan perintah echo susulan, output semata -mata 12345 Tanpa sebarang garis baru:

    $ untuk i dalam $ (ls *.txt 2>/dev/null); lakukan echo -n "$ (ekor -n1 $ i)"; Selesai 12345 $
    Salinan

    Perhatikan bagaimana bahkan garis baru terakhir tidak hadir, oleh itu output sebelum petikan $ pulangan.

    Akhirnya kita ada echo "dari $ i !"; (menunjukkan kepada kita dari 1.txt ! output) dan penutupan gelung oleh selesai.

    Saya percaya sekarang anda dapat melihat betapa kuatnya ini, dan berapa banyak kawalan yang dapat dilakukan oleh fail, kandungan dokumen dan banyak lagi!

    Mari menghasilkan rentetan rawak yang panjang dengan gelung sementara seterusnya! Menyeronokkan?

  5. Menggunakan gelung sementara untuk menghasilkan rentetan rawak:
    $ Random = "$ (tarikh +%s%n | potong -b14-19)" $ count = 0; MyRandom =; Walaupun benar; Do count = $ [$ count + 1]; jika [$ count -gt 10]; kemudian pecah; fi; Myrandom = "$ myrandom $ (echo" $ random "| sed's |^\ (.\).*| \ 1 | ') "; selesai; echo" $ myrandom "6421761311
    Salinan

    Itu kelihatan rumit! Mari kita menganalisis langkah demi langkah. Tetapi pertama, mari kita lihat bagaimana ini akan kelihatan di dalam skrip bash.

  6. Contoh fungsi yang sama, dilaksanakan di dalam skrip bash:
    Ujian CAT $.sh #!/bin/bash rawak = "$ (tarikh +%s%n | potong -b14-19)" count = 0 myrandom = while true; do count = $ [$ count + 1] if [$ count -gt 10]; kemudian pecah fi myrandom = "$ myrandom $ (echo" $ random "| sed's |^\ (.\).*| \ 1 | ') "Selesai echo" $ myrandom "
    Salinan
    $ chmod +x ujian.sh $ ./ujian.SH 1111211213 $ ./ujian.SH 1212213213 

    Ia agak mengejutkan pada masa-masa bahawa kod gelung bash kompleks itu boleh dengan mudah dipindahkan ke 'satu-liner' (istilah yang digunakan oleh pemaju bash untuk merujuk kepada realiti skrip kecil tetapi dilaksanakan secara langsung dari baris arahan, biasanya pada bujang (atau maksimum beberapa).



    Mari kita mula menganalisis dua contoh terakhir kita - yang sangat serupa. Perbezaan kecil dalam kod, terutamanya di sekitar idiom ';' dijelaskan dalam Contoh 7 di bawah:

    Rawak = "$ (tarikh +%s%n | potong -b14-19)" pada baris 4: Ini memerlukan (menggunakan CUT -B14-19) 6 digit terakhir masa zaman semasa (bilangan detik yang telah berlalu sejak 1 Januari 1970) seperti yang dilaporkan oleh tarikh +%s%n dan memberikan rentetan yang dihasilkan kepada pemboleh ubah rawak, dengan itu menetapkan entropi separa rawak ke kolam rawak, dengan istilah mudah "menjadikan kolam rawak agak lebih rawak".
    Kiraan = 0 pada baris 6: Tetapkan Hitung pemboleh ubah kepada 0
    MyRandom = pada baris 7: Tetapkan Myrandom pemboleh ubah kepada 'kosong' (tiada nilai yang diberikan)
    Semasa ... lakukan ... selesai Antara baris 9 dan baris 15: Ini harus jelas sekarang; Mulakan beberapa gelung, jalankan kod antara klausa yang dilakukan ...
    Benar: dan selagi pernyataan yang mengikuti 'sementara' dinilai sebagai benar, gelung akan diteruskan. Di sini pernyataan itu 'benar' yang bermaksud bahawa ini adalah gelung yang tidak terbatas, sehingga rehat pernyataan diberikan.
    Count = $ [$ Count + 1] pada baris 10: Tingkatkan kami Hitung pemboleh ubah oleh 1
    jika [$ count -gt 10]; kemudian pada baris 11: pernyataan jika untuk memeriksa sama ada pemboleh ubah kami lebih besar kemudian -GT 10, Dan jika demikian, laksanakan .. fi bahagian
    rehat pada baris 12: ini akan memecahkan gelung semasa (i.e. bila Hitung lebih besar ketika itu 10 gelung akan berakhir)
    Myrandom = ".. pada baris 14: Kami akan memberikan nilai baru kepada Myrandom
    $ Myrandom Pada baris 14: Pertama, ambil apa yang kita ada di dalam pembolehubah ini, dengan kata lain, kita akan menambahkan sesuatu pada akhir apa yang sudah ada, dan ini untuk setiap gelung berikutnya
    $ (echo "$ random" | sed's |^\ ((.\).*| \ 1 | ') pada baris 14: ini adalah bahagian yang ditambah setiap kali. Pada asasnya, ia echo adalah Rawak berubah -ubah dan mengambil watak pertama output itu menggunakan ekspresi biasa yang kompleks di sed. Anda boleh mengabaikan bahagian itu jika anda suka, pada dasarnya ia menyatakan "mengambil watak pertama dari $ Rawak output berubah -ubah dan buang segala yang lain "

    Anda dapat melihat bagaimana output (contohnya 1111211213) dijana; Satu watak (kiri ke kanan) pada masa itu, menggunakan gelung sementara, yang gelung 10 kali akibat daripada Hitung Pemeriksaan pembolehubah kaunter.

    Jadi mengapa output sering dalam format 1,2,3 dan kurang nombor lain? Ini kerana Rawak pembolehubah mengembalikan pemboleh ubah separa rawak (berdasarkan Rawak =… benih) yang berada dalam lingkungan 0 hingga 32767. Oleh itu, selalunya nombor ini akan bermula dengan 1, 2 atau 3. Contohnya 10000-19999 semuanya akan kembali 1 dan lain-lain. Sebagai watak pertama output selalu diambil oleh sed!

  7. Skrip pendek untuk menyerlahkan kemungkinan untuk mengatur kod gelung bash (atau gaya) dengan cara yang berbeza tanpa menggunakan ; Idiom.

    Kita perlu menjelaskan perbezaan kecil skrip bash berbanding skrip baris perintah satu liner.

    CATATAN
    Perhatikan bahawa dalam skrip bash (ujian.sh) tidak banyak ; Idioms. Ini kerana kita kini telah memecah kod melalui pelbagai baris, dan a ; adalah tidak diperlukan apabila terdapat watak EOL (akhir garis). Watak seperti itu (Newline atau Carriage Return) tidak dapat dilihat di kebanyakan editor teks tetapi ia adalah penjelasan diri jika anda berfikir tentang fakta bahawa setiap arahan berada pada baris yang berasingan.

    Perhatikan juga bahawa anda boleh meletakkan lakukan fasal manakala gelung pada baris seterusnya juga, sehingga menjadi tidak perlu untuk menggunakannya ; di sana.

    $ CAT TEST2.sh #!/bin/bash untuk i dalam $ (seq 1 3) do echo "... looping ... $ i ..." selesai
    Salinan
    $ ./test2.Sh ... gelung ... 1 ... gelung ... 2 ... gelung ... 3 .. 

    Saya secara peribadi lebih suka gaya sintaks yang diberikan Contoh 6, kerana nampaknya lebih jelas apa niat kod itu dengan menulis pernyataan gelung sepenuhnya pada satu baris (sama dengan bahasa pengekodan lain), walaupun pendapat dan gaya sintaks berbeza setiap pemaju, atau setiap komuniti pemaju.

  8. Akhirnya, marilah kita melihat bash 'sehingga' gelung:
    $ Nr = 0; sehingga [$ nr -eq 5]; lakukan echo "$ nr"; Nr = $ [$ nr + 1]; Selesai 0 1 2 3 4
    Salinan

    Mari analisis contoh ini:

    NR = 0: Di sini tetapkan pemboleh ubah bernama Nr, hingga sifar
    sehingga: Kami memulakan gelung 'sehingga' kami
    [$ Nr -eq 5]: Ini kita jika keadaan, atau lebih baik kita sehingga keadaan. Saya katakan jika Oleh kerana sintaks (dan kerja) adalah serupa dengan arahan ujian, i.e. arahan bawah yang digunakan dalam jika pernyataan. Di bash, arahan ujian juga boleh diwakili oleh single ["] kurungan. The $ Nr -eq 5 Ujian bermaksud; Apabila pemboleh ubah kami Nr mencapai 5, maka ujian akan menjadi kenyataan, seterusnya menjadikannya sehingga gelung berakhir kerana keadaan dipadankan (cara lain untuk membaca ini adalah 'sehingga benar' atau 'sehingga pembolehubah NR kami sama dengan 5'). Perhatikan bahawa sekali NR adalah 5, kod gelung tidak lagi dilaksanakan, oleh itu 4 adalah nombor terakhir yang dipaparkan.
    ;: Menamatkan pernyataan sehingga kami, seperti yang dijelaskan di atas
    lakukan: Mulakan rantaian tindakan kami untuk dilaksanakan sehingga pernyataan yang diuji menjadi benar/sah
    echo "$ nr;": echo keluar nilai semasa pemboleh ubah kami Nr
    Nr = $ [$ nr + 1];: Meningkatkan pemboleh ubah kita dengan satu. The $ ['...'] Kaedah pengiraan khusus untuk bash
    selesai: Menamatkan kod rantaian/gelung tindakan kami

    Seperti yang anda lihat, semasa dan sehingga gelung sangat serupa, walaupun sebenarnya mereka bertentangan. Sementara gelung dilaksanakan selagi sesuatu adalah benar/sah, sedangkan sehingga gelung dilaksanakan selagi sesuatu adalah 'belum sah/benar'. Selalunya mereka boleh ditukar ganti dengan membalikkan keadaan.

  9. Kesimpulan

    Saya percaya anda boleh mula melihat kekuatan bash, dan terutama untuk, sementara dan sehingga gelung bash. Kami hanya menggaruk permukaan di sini, dan saya mungkin akan kembali kemudian dengan contoh maju lebih lanjut. Sementara itu, tinggalkan kami komen tentang bagaimana anda menggunakan gelung bash dalam tugas atau skrip sehari-hari anda. Nikmati!

Tutorial Linux Berkaitan:

  • Gelung bersarang dalam skrip bash
  • Menguasai Gelung Skrip Bash
  • Pengenalan kepada Automasi, Alat dan Teknik Linux
  • Perkara yang hendak dipasang di Ubuntu 20.04
  • Pengurusan skrip & proses bash berbilang threaded di…
  • Perkara yang perlu dilakukan setelah memasang ubuntu 20.04 Focal Fossa Linux
  • Sistem Hung Linux? Cara melarikan diri ke baris arahan dan ..
  • Mengendalikan input pengguna dalam skrip bash
  • Mint 20: Lebih baik daripada Ubuntu dan Microsoft Windows?
  • Perkara yang perlu dipasang di Ubuntu 22.04