Rumah - Laptop
Bash sambil loop tak terbatas. Perulangan while tak terbatas dalam skrip BASH

Pengarang: Paul Cobbaut
Tanggal terbit: 16 Oktober 2014
Terjemahan: A.Panin
Tanggal penerjemahan: 21 Desember 2014

Bab 22. Perulangan dalam Skrip

perintah tes

Perintah test memungkinkan Anda menentukan apakah suatu ekspresi benar atau salah. Mari kita mulai dengan menguji apakah nilai bilangan bulat 10 lebih besar dari nilai bilangan bulat 55. $ test 10 -gt 55 ; gema $? $1

Perintah test mengembalikan 1 jika ekspresi salah. Dan, seperti yang akan Anda lihat pada contoh berikut, perintah test akan mengembalikan 0 jika ekspresi bernilai benar.

$uji 56 -gt 55 ; gema $? $0

Jika Anda lebih nyaman bekerja dengan string benar dan salah, Anda dapat menggunakan perintah test seperti yang ditunjukkan di bawah ini.

$ tes 56 -gt 55 && gema benar || gema salah benar $ tes 6 -gt 55 && gema benar || gema salah salah Perintah test juga bisa diganti dengan tanda kurung siku, sehingga perintah pada contoh di bawah sama persis dengan perintah pada contoh di atas. pelaksanaan berbagai pemeriksaan.< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar читаемым файлом? [ foo -nt bar ] Новее ли файл foo файла bar ? [ -o nounset ] Активирован ли параметр командной оболочки nounset ?

[ -d foo ] Apakah direktori foo ada? [ -e bar ] Apakah file barnya ada? [ "/etc" = $PWD ] Apakah /etc setara dengan nilai $PWD ? [ $1 != "secret" ] Apakah nilai parameter skrip pertama berbeda dari string rahasia? [ 55 -lt $bar ] Apakah nilai bilangan bulat 55 lebih kecil dari nilai $bar ? [ $foo -ge 1000 ] Apakah nilai $foo lebih besar atau sama dengan nilai integer 1000 ? ["abc"

Operator pengujian dapat digabungkan dengan operator yang sesuai dengan operator logika "DAN" dan "ATAU".

paul@RHEL4b:~$ [ 66 -gt 55 -a 66 -lt 500 ] && gema benar || gema salah benar paul@RHEL4b:~$ [ 66 -gt 55 -a 660 -lt 500 ] && gema benar || echo false false paul@RHEL4b:~$ [ 66 -gt 55 -o 660 -lt 500 ] && echo benar || gema salah benar

Lompatan bersyarat jika maka yang lain Konstruk if else dimaksudkan untuk memilih opsi kode. Jika kondisi tertentu benar, beberapa kode akan dieksekusi, jika tidak, beberapa kode lainnya akan dieksekusi. Contoh di bawah ini memeriksa keberadaan file, setelah itu, jika asumsi keberadaan file dikonfirmasi, pesan terkait akan ditampilkan.#!/bin/bash if [ -f isit.txt ] lalu echo file isit.txt ada! jika tidak, file gema isit.txt tidak ditemukan! fi

Jika kita menabung

kode ini skrip dalam file bernama "pilihan", dapat dijalankan dengan cara yang sama.$ ./file pilihan isit.txt tidak ditemukan! $ sentuh isit.txt $ ./pilihan file isit.txt ada! $

Lompatan bersyarat jika kemudian elif

Anda dapat memposting operator baru

lompatan bersyarat

Skrip yang sangat mirip dengan yang disajikan di atas dapat dibuat tanpa menggunakan shell bawaan dengan menggunakan deklarasi bash shell untuk rentang nilai (dari nilai..hingga nilai).

#!/bin/bash untuk counter di (1..20) lakukan penghitungan gema dari 1 hingga 20, nilai saat ini $counter sleep 1 selesai DI DALAM siklus ini for menggunakan mekanisme untuk mencari file berdasarkan pola (diimplementasikan sebagai bagian dari mekanisme perluasan perintah). Jika petunjuk di atas diposting langsung di baris perintah

, itu akan berfungsi sama.

kahlan@solexp11$ ls count.ksh go.ksh kahlan@solexp11$ untuk file di *.ksh ; lakukan cp $file $file.cadangan; selesai kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

sementara lingkaran

Di bawah ini adalah contoh sederhana penggunaan perulangan while.

saya=100; sementara [ $i -ge 0 ] ; lakukan echo Hitung mundur dari 100 ke 0, nilai saat ini $i;

biarkan aku--; Selesai

Perulangan tak terbatas dapat diimplementasikan menggunakan deklarasi while true atau while:, dengan simbol: setara dengan operasi yang hilang di shell Korn dan bash. #!/bin/ksh # loop tak berujung sementara: do echo hello sleep 1 selesai Sampai berputar

Di bawah ini adalah contoh sederhana penggunaan loop hingga.

misalkan i=100; sampai [ $i -le 0 ] ; lakukan echo Hitung mundur dari 100 ke 1, nilai saat ini $i;

biarkan aku--; Selesai

Latihan: Tes dan Perulangan dalam Skrip

3. Mengembangkan skrip yang akan digunakan

sementara lingkaran

untuk menghitung dari 3 sampai 7.

4. Kembangkan skrip yang akan menggunakan perulangan hingga untuk menghitung mundur dari 8 hingga 4.

5. Kembangkan skrip yang akan menghitung file dengan ekstensi .txt di direktori saat ini.
Dalam setiap iterasi perulangan, nilai berikutnya dari daftar akan ditulis ke variabel var. Oleh karena itu, lintasan pertama dari perulangan akan menggunakan nilai pertama dari daftar. Yang kedua - yang kedua, dan seterusnya - hingga loop mencapai elemen terakhir.

Mengulangi nilai-nilai sederhana

Mungkin contoh paling sederhana dari perulangan for dalam skrip bash adalah mengulangi daftar nilai sederhana:

#!/bin/bash untuk var di detik pertama ketiga keempat kelima do echo Item $var selesai
Hasil skrip ini ditunjukkan di bawah ini. Anda dapat melihat dengan jelas bahwa variabel $var berisi elemen dari daftar secara berurutan. Hal ini terjadi hingga siklus mencapai siklus terakhirnya.


Sederhana untuk perulangan

Harap dicatat bahwa variabel $var mempertahankan nilainya ketika keluar dari loop, isinya dapat diubah, dan secara umum, Anda dapat menggunakannya seperti variabel lainnya.

Mengulangi nilai-nilai kompleks

Daftar yang digunakan untuk menginisialisasi perulangan for tidak hanya berisi string sederhana yang terdiri dari satu kata, tetapi juga seluruh frasa yang berisi beberapa kata dan tanda baca. Misalnya, mungkin terlihat seperti ini:

#!/bin/bash untuk var di yang pertama "yang kedua" "yang ketiga" "Saya akan melakukannya" do echo "Ini: $var" selesai
Inilah yang terjadi setelah loop ini melewati daftar. Seperti yang Anda lihat, hasilnya cukup diharapkan.


Mengulangi nilai-nilai kompleks
TNW-CUS-FMP - kode promo untuk diskon 10% pada layanan kami, tersedia untuk aktivasi dalam 7 hari"

Menginisialisasi loop dengan daftar yang diperoleh dari hasil perintah

Cara lain untuk menginisialisasi perulangan for adalah dengan meneruskannya ke daftar, yang merupakan hasil dari sebuah perintah. Di sini substitusi perintah digunakan untuk menjalankannya dan mendapatkan hasil pekerjaannya.

#!/bin/bash file="myfile" untuk var di $(cat $file) do echo " $var" selesai
Contoh ini menggunakan perintah cat, yang membaca isi file. Daftar nilai yang dihasilkan diteruskan ke loop dan ditampilkan di layar. Harap dicatat bahwa file yang kami akses berisi daftar kata yang dipisahkan oleh baris baru;


Sebuah loop yang mengulang isi file

Di sini kita harus memperhitungkan bahwa pendekatan seperti itu, jika pemrosesan data baris demi baris diharapkan, tidak akan berfungsi untuk file yang lebih besar dari struktur yang kompleks, barisnya dapat berisi beberapa kata yang dipisahkan oleh spasi. Perulangan akan memproses setiap kata, bukan baris.

Bagaimana jika ini bukan yang Anda butuhkan?

Pemisah lapangan

Alasan fitur di atas adalah yang spesial variabel lingkungan, yang disebut IFS (Internal Field Separator) dan memungkinkan Anda menentukan pemisah bidang. Secara default, bash shell menganggap karakter berikut sebagai pemisah bidang:
  • Ruang angkasa
  • karakter tab
  • Karakter umpan baris
Jika bash menemukan salah satu karakter ini dalam data, maka diasumsikan bahwa karakter tersebut didahului oleh nilai independen berikutnya dalam daftar.

Untuk mengatasi masalah ini, Anda dapat mengubahnya untuk sementara variabel lingkungan JIKA. Berikut cara melakukannya dalam skrip bash, dengan asumsi Anda hanya memerlukan baris baru sebagai pemisah bidang:

IFS=$"\n"
Setelah Anda menambahkan perintah ini ke skrip bash Anda, itu akan berfungsi seperti yang diharapkan, mengabaikan spasi dan tab dan hanya memperlakukan karakter baris baru sebagai pemisah bidang.

#!/bin/bash file="/etc/passwd" IFS=$"\n" untuk var di $(cat $file) lakukan echo " $var" selesai
Jika skrip ini dijalankan, skrip ini akan menampilkan apa yang diperlukan, memberikan, dalam setiap iterasi loop, akses ke baris berikutnya yang ditulis ke file.


Penjelajahan baris demi baris suatu file dalam perulangan for

Pemisah juga bisa berupa karakter lain. Misalnya di atas kami menampilkan isi file /etc/passwd. Data pengguna pada baris dipisahkan dengan titik dua. Jika Anda perlu memproses string tersebut dalam satu lingkaran, IFS dapat dikonfigurasi seperti ini:

Melintasi file yang terdapat dalam direktori

Salah satu penggunaan for loop yang paling umum dalam skrip bash adalah untuk melintasi file yang terletak di direktori dan memproses file tersebut.

Misalnya, berikut cara membuat daftar file dan folder:

#!/bin/bash untuk file di /home/likegeeks/* lakukan if [ -d "$file" ] lalu echo "$file adalah direktori" elif [ -f "$file" ] lalu echo "$file adalah a file" selesai
Jika Anda memahami materi sebelumnya dalam rangkaian artikel ini, Anda harus memahami struktur konstruksi if-then, serta cara membedakan file dari folder. Jika Anda kesulitan memahami kode di atas, baca kembali materi ini.

Inilah yang akan dihasilkan oleh skrip.


Menampilkan isi folder

Perhatikan bagaimana kita menginisialisasi loop, yaitu wildcard "*" di akhir alamat folder. Simbol ini dapat dianggap sebagai karakter pengganti yang berarti: “semua file dengan nama apa pun.” itu memungkinkan Anda untuk mengatur substitusi otomatis nama file yang sesuai dengan polanya.

Saat menguji suatu kondisi dalam pernyataan if, kami menyertakan nama variabel dalam tanda kutip. Hal ini dilakukan karena nama file atau folder mungkin mengandung spasi.

Gaya C untuk loop

Jika Anda familiar dengan bahasa pemrograman C, sintaks untuk mendeskripsikan bash for loop mungkin terasa aneh bagi Anda, karena Anda jelas terbiasa mendeskripsikan loop dengan cara ini:

Untuk (saya = 0; saya< 10; i++) { printf("number is %d\n", i); }
Dalam skrip bash Anda dapat menggunakan loop for, yang deskripsinya terlihat sangat mirip dengan loop gaya C, meskipun ada beberapa perbedaan. Diagram siklus dengan pendekatan ini terlihat seperti ini:

For ((nilai awal variabel; kondisi untuk mengakhiri loop; perubahan variabel))
Di bash dapat ditulis seperti ini:

Untuk ((Sebuah = 1; Sebuah< 10; a++))
Berikut ini contoh yang berfungsi:

#!/bin/bash untuk ((i=1; i<= 10; i++)) do echo "number is $i" done
Kode ini akan menampilkan daftar angka dari 1 hingga 10.

Perulangan dalam gaya C

sementara lingkaran

Konstruksi for bukan satu-satunya cara untuk mengatur loop dalam skrip bash. Anda juga dapat menggunakan perulangan while di sini. Dalam perulangan seperti itu, Anda dapat menentukan perintah untuk memeriksa kondisi tertentu dan mengeksekusi badan perulangan hingga kondisi yang diperiksa mengembalikan nol, atau sinyal untuk berhasil menyelesaikan operasi tertentu. Ketika kondisi perulangan mengembalikan nilai bukan nol, yang berarti kesalahan, perulangan akan berhenti.

Berikut adalah diagram organisasi perulangan while
sementara perintah pemeriksaan kondisi
Mengerjakan
tim lain
Selesai

Mari kita lihat contoh skrip dengan loop seperti ini:

#!/bin/bash var1=5 sementara [ $var1 -gt 0 ] lakukan echo $var1 var1=$[ $var1 - 1 ] selesai
Di pintu masuk loop, diperiksa apakah variabel $var1 lebih besar dari nol. Jika demikian, badan perulangan akan dieksekusi, di mana nilai variabel dikurangkan satu. Ini terjadi di setiap iterasi, dan kami mencetak nilai variabel ke konsol sebelum diubah. Segera setelah $var1 mencapai nilai 0, perulangan berhenti.

Hasil dari perulangan while

Jika Anda tidak mengubah variabel $var1, ini akan menyebabkan skrip berakhir dalam loop tak terbatas.

Loop Bersarang

Anda dapat menggunakan perintah apa pun di badan perulangan, termasuk meluncurkan perulangan lainnya. Konstruksi seperti ini disebut loop bersarang:

#!/bin/bash untuk ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
Di bawah ini adalah apa yang akan dihasilkan oleh skrip ini. Seperti yang Anda lihat, pertama-tama iterasi pertama dari loop luar dilakukan, kemudian tiga iterasi dari loop dalam, setelah selesai, loop luar ikut bermain lagi, lalu loop dalam lagi.

Loop Bersarang

Memproses Isi File

Paling sering, loop bersarang digunakan untuk memproses file. Jadi, loop luar mengulangi baris-baris file, dan loop dalam sudah bekerja dengan setiap baris. Di sini, misalnya, tampilan pemrosesan file /etc/passwd:

#!/bin/bash IFS=$"\n" untuk entri di $(cat /etc/passwd) do echo "Nilai di $entry –" IFS=: untuk nilai di $entry do echo "$value" selesai Selesai
Ada dua loop dalam skrip ini. Yang pertama melewati baris menggunakan karakter baris baru sebagai pemisah. Yang internal sibuk mengurai string yang bidangnya dipisahkan oleh titik dua.

Pemrosesan Data Berkas

Pendekatan ini dapat digunakan saat memproses file CSV, atau file serupa lainnya, dengan menulis karakter pemisah ke dalam variabel lingkungan IFS sesuai kebutuhan.

Manajemen siklus

Mungkin, setelah memasuki perulangan, Anda harus menghentikannya ketika variabel perulangan mencapai nilai tertentu yang tidak sesuai dengan kondisi yang ditentukan awal untuk mengakhiri perulangan. Dalam situasi seperti ini, apakah perlu menunggu siklus selesai secara normal? Tentu saja tidak, dan dalam kasus seperti ini, dua perintah berikut akan berguna:
  • merusak
  • melanjutkan

perintah istirahat

Perintah ini memungkinkan Anda untuk menghentikan eksekusi loop. Ini dapat digunakan untuk perulangan for dan while:

#!/bin/bash untuk var1 di 1 2 3 4 5 6 7 8 9 10 lakukan if [ $var1 -eq 5 ] lalu break fi echo "Nomor: $var1" selesai
Perulangan seperti itu, dalam kondisi normal, akan melewati seluruh daftar nilai dari daftar. Namun, dalam kasus kita, eksekusinya akan terhenti ketika variabel $var1 sama dengan 5.

Keluar dari loop for lebih awal

Ini adalah hal yang sama, tetapi untuk perulangan while:

#!/bin/bash var1=1 while [ $var1 -lt 10 ] lakukan jika [ $var1 -eq 5 ] lalu hancurkan fi echo "Iterasi: $var1" var1=$(($var1 + 1)) selesai
Perintah break, dijalankan ketika $var1 mencapai 5, memutus perulangan. Konsol akan menampilkan hal yang sama seperti pada contoh sebelumnya.

lanjutkan perintah

Ketika perintah ini ditemukan di badan perulangan, perulangan saat ini berakhir lebih awal dan perulangan berikutnya dimulai, tanpa keluar dari perulangan. Mari kita lihat perintah continue pada perulangan for:

#!/bin/bash untuk ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
Ketika kondisi di dalam loop terpenuhi, yaitu ketika $var1 lebih besar dari 5 dan kurang dari 10, shell akan mengeksekusi perintah continue. Hal ini mengakibatkan melewatkan perintah yang tersisa di badan perulangan dan melanjutkan ke iterasi berikutnya.

Perintah lanjutkan dalam perulangan for

Memproses Output Berjalan dalam Satu Lingkaran

Output data dari loop dapat diproses dengan mengarahkan output atau meneruskannya ke pipeline. Hal ini dilakukan dengan menambahkan perintah pemrosesan keluaran setelah pernyataan selesai.

Misalnya, alih-alih menampilkan di layar apa yang dihasilkan dalam satu lingkaran, Anda dapat menulis semuanya ke file atau meneruskannya ke tempat lain:

#!/bin/bash untuk ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt echo "selesai."
Shell akan membuat file myfile.txt dan mengarahkan output pernyataan for ke file tersebut. Mari kita buka file tersebut dan pastikan file tersebut berisi apa yang kita harapkan.

Arahkan ulang keluaran loop ke file

Contoh: Cari file yang dapat dieksekusi

Mari gunakan apa yang telah kita bahas dan tulis sesuatu yang bermanfaat. Misalnya, jika Anda perlu mengetahui file executable mana yang tersedia di sistem, Anda dapat memindai semua folder yang direkam dalam variabel lingkungan PATH. Kami sudah memiliki seluruh peralatan yang kami perlukan untuk ini, kami hanya perlu menggabungkan semuanya:

#!/bin/bash IFS=: untuk folder di $PATH lakukan echo "$folder:" untuk file di $folder/* lakukan if [ -x $file ] lalu echo " $file" fi selesai selesai
Skrip ini, kecil dan sederhana, memungkinkan kami mendapatkan daftar file yang dapat dieksekusi yang disimpan dalam folder dari PATH.

Mencari file yang dapat dieksekusi dalam folder dari variabel PATH

Hasil

Hari ini kita berbicara tentang loop for dan while dalam skrip bash, cara menjalankannya, dan cara mengelolanya. Sekarang Anda tahu cara memproses string dengan pembatas berbeda dalam loop, Anda tahu cara mengarahkan output data dalam loop ke file, cara melihat dan menganalisis konten direktori.

Jika kami berasumsi bahwa Anda adalah pengembang skrip bash yang hanya mengetahui apa yang dinyatakan di bagian pertama rangkaian artikel ini, dan di bagian kedua ini, maka Anda sudah dapat menulis sesuatu yang bermanfaat. Di depan adalah bagian ketiga, setelah memahaminya Anda akan mempelajari cara meneruskan parameter dan sakelar baris perintah ke skrip bash, dan apa yang harus dilakukan dengan itu semua.

Penjelasan singkat tentang perbedaan jenis loop:

for - akan melakukan suatu tindakan selama ada objek yang akan dieksekusi (misalnya, membaca aliran dari stdin, file, atau fungsi);
while - melakukan tindakan hingga kondisi itu benar;
sampai - akan dieksekusi selama kondisi tidak akan menjadi kenyataan, mis. untuk saat ini itu salah.

UNTUK Lingkaran

Mari pertimbangkan versi skrip ini dengan perulangan:

$ cat loop.sh #!/bin/bash untuk variabel di `ls -1` do echo "$variable" selesai

Sintaksnya sangat sederhana dan ditunjukkan dengan cukup jelas pada contoh:

for (memulai loop) variabel (mendeklarasikan variabel dimana kita akan melakukan tindakan) in (mengirim aliran ke loop) `ls -1` (perintah untuk dieksekusi dan diteruskan ke variabel $variable). Lakukan dan selesai adalah "tubuh" dari perulangan, di mana tindakan utama akan dilakukan pada data yang diterima, dan echo "$variable" adalah tindakan aktual yang dilakukan oleh perulangan.

Sekarang mari kita ubah sedikit contohnya, dan alih-alih menentukan perintah secara eksplisit, kita akan menggunakan variabel kedua:

$ cat loop.sh #!/bin/bash ls=`ls -1` untuk variabel di $ls do echo "$variable" selesai

Sekarang perintah ls -1 diteruskan dalam variabel terpisah, yang memungkinkan Anda bekerja dengan loop dengan lebih fleksibel. Selain variabel dalam satu lingkaran, Anda juga bisa menggunakan fungsi:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) untuk variabel di `lsl` lakukan echo "$variable" selesai

Kondisi utama dari perulangan for adalah bahwa perulangan tersebut akan dieksekusi selama perintah yang diteruskan ke perulangan tersebut berisi objek untuk tindakan. Berdasarkan contoh di atas - selama ls -1 memiliki file untuk ditampilkan - loop akan meneruskannya ke variabel dan mengeksekusi "loop body". Segera setelah daftar file dalam direktori berakhir, loop akan menyelesaikan eksekusinya.

Mari kita buat contohnya sedikit lebih rumit.

Direktori berisi daftar file:

$ ls -1 file1 file2 file3 file4 file5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

Kita perlu memilih dari mereka hanya yang tidak memiliki kata " TIDAK«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` untuk variabel di $lsl do echo "$variable" | grep -v "tidak" selesai $ ./loop.sh file1 file2 file3 file4 file5 loop.sh

Anda juga dapat menggunakan ekspresi kondisional dalam satu lingkaran ( ekspresi kondisional) […] untuk memeriksa kondisi dan pernyataan break untuk menghentikan perulangan jika kondisi dipicu.

Perhatikan contoh ini:

$ cat loop.sh #!/bin/bash lsl=`ls -1` untuk variabel di $lsl lakukan if [ $variable != "loop.sh" ] lalu echo "$variable" | grep -v "tidak" lagi break fi selesai

Perulangan akan berlanjut hingga file loop.sh ditemukan. Segera setelah eksekusi loop mencapai file ini, loop akan diinterupsi oleh perintah break:

$ ./loop.sh file1 file2 file3 file4 file5

Contoh lainnya adalah penggunaan operasi aritmatika sesaat sebelum mengeksekusi badan perulangan:

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

Di sini kita menetapkan tiga perintah kontrol - count=1, kondisi pengontrol - ketika hitungan kurang dari 11, dan perintah untuk mengeksekusi - hitungan +1:

WHILE dan UNTIL perulangan

Contoh sederhana yang dengan jelas menunjukkan cara kerja perulangan while:

$ cat loop.sh #!/bin/bash count=0 sementara [ $count -lt 10 ] lakukan ((count++)) echo $count selesai

Kita menyetel variabel $count ke nol, dan kemudian menjalankan perulangan while dengan kondisi “sementara $count kurang dari sepuluh, jalankan perulangan.” Di badan loop kita mengeksekusi kenaikan postfix Memberi +1 pada variabel $count dan hasilnya dicetak ke stdout.

Hasil eksekusi:

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

Segera setelah nilai variabel $count menjadi 10, perulangan berhenti.

Contoh bagus dari perulangan "tak terbatas" yang menunjukkan cara kerja while:

$ cat loop.sh #!/bin/bash count=10 while [ 1 = 1 ] lakukan ((count++)) echo $count selesai $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^C

Perulangan sampai bekerja dengan cara yang sama, tetapi dalam arah yang berlawanan:

$ cat loop.sh #!/bin/bash count=0 sampai [ $count -gt 10 ] lakukan ((count++)) echo $count selesai

Di sini kita menetapkan kondisi serupa, namun alih-alih “selama variabelnya kurang dari 10”, kita menentukan “sampai variabelnya menjadi lebih besar dari 10”. Hasil eksekusi:

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

Jika contoh “loop tak berujung” di atas dijalankan menggunakan sampai, maka tidak akan menghasilkan apa pun, tidak seperti while:

$ cat loop.sh #!/bin/bash count=10 sampai [ 1 = 1 ] lakukan ((count++)) echo $count selesai $ ./loop.sh $

Karena " kondisi"semula" BENAR"—badan perulangan tidak akan dieksekusi.

Sama seperti pada perulangan for, Anda dapat menggunakan fungsi dalam while dan Until. Misalnya, perulangan dari skrip kehidupan nyata yang memeriksa status server Kucing jantan(PID diambil dari sistem SLES, mungkin berbeda di sistem lain), versi yang sedikit disederhanakan:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep Tomcat | grep -v grep | grep java | awk "(print $2)"` ) sementara check_tomcat_status lakukan if [ -n "$ RUN" ] lalu printf "PERINGATAN: Tomcat masih berjalan dengan PID $RUN."

Hasil eksekusi:

else printf "Tomcat berhenti, melanjutkan...nn" break fi selesai

$ ./loop.sh PERINGATAN: Tomcat masih berjalan dengan PID 14435 26548.PERINGATAN: Tomcat masih berjalan dengan PID 14435 26548.PERINGATAN: Tomcat masih berjalan dengan PID 14435 26548.PERINGATAN: Tomcat masih berjalan dengan PID 14435 26548.PERINGATAN: Tomcat masih berjalan dengan PID 14435 26548.PERINGATAN: Tomcat masih berjalan dengan PID 14435 26548.PERINGATAN: Tomcat masih berjalan dengan PID 14435 26548.PERINGATAN: Tomcat masih berjalan dengan PID 14435

Versi lengkap:

Check_tomcat_status () ( RUN=`ps aux | grep Tomcat | grep -v grep | grep java | awk "(print $2)"` ) sambil check_tomcat_status; lakukan if [ -n "$RUN" ] lalu printf "PERINGATAN: Tomcat masih berjalan dengan PID $RUN. Hentikan?" jawab "Menghentikan Tomcat..." "Melanjutkan instalasi..." && $CATALINA_HOME/bin/shutdown .sh 2&>1 /dev/null || break sleep 2 if [ -n "$RUN" ] lalu printf "Tomcat masih berjalan. Bunuh?" jawab "Membunuh Tomcat..." "Melanjutkan instalasi...n" && kill $RUN || break sleep 2 fi else printf "Tomcat berhenti, melanjutkan...nn" break fi selesai

Jawaban () ( saat membaca respons; lakukan echo case $response in |) printf "$1n" return 0 break ;;

|) printf "$2n" kembalikan 1 istirahat ;;

*) printf "Silakan masukkan Y(ya) atau N(tidak)!" esac selesai ) Di sini dimungkinkan untuk menggunakan while dan sampai - tetapi bukan perulangan for, karena for akan berfungsi satu kali (menerima PID dan mengakhiri). Loop adalah hal yang sangat berguna saat menulis program atau skrip apa pun, bahkan diperlukan. Mereka memungkinkan kita untuk mengeksekusi bagian kode tertentu beberapa kali. Secara alami, bash memiliki beberapa jenis loop. Kami akan menjelaskan siklusnya

untuk di, untuk, sementara, sampai:

. Meskipun for in dan for dianggap sebagai sintaksis yang berbeda dari pernyataan yang sama, menurut saya keduanya lebih berbeda satu sama lain daripada while dari sampai. Ulangi dengan penghitung untuk masuk Siklus
untuk di
Ini adalah loop dengan penghitung. Blok kode yang terletak di badan loop diulang sebanyak nilai yang terkandung dalam daftar operator for in, dan dengan setiap pengulangan, variabel counter (di sini disebut var, tapi tentu saja Anda dapat menyebutnya apa pun yang Anda suka) memiliki nilai elemen berikutnya dalam daftar.<список>Jika kata kunci do berada pada baris yang sama dengan kata for, maka setelah daftar argumen (sebelum do) Anda harus memberi tanda titik koma.<списке>Masing-masing elemen
mungkin berisi banyak argumen. Ini berguna saat memproses sekelompok parameter. Dalam hal ini, untuk memaksa penguraian setiap argumen di
#!/bin/bash untuk counter di (1..20) lakukan penghitungan gema dari 1 hingga 20, nilai saat ini $counter sleep 1 selesai<списке>, Anda harus menggunakan instruksi set
Anda dapat menggunakan variabel sebagai daftar dalam perulangan for.<список>Perulangan for dapat menggunakan nama file, yang pada gilirannya dapat berisi karakter wildcard. Ini bisa sangat berguna saat bekerja dengan file dalam jumlah besar.
Jika
tidak ditentukan dalam loop for, maka variabel $@ digunakan sebagai daftar argumen baris perintah.

Saat membuat daftar argumen, Anda dapat menggunakan substitusi perintah dalam perulangan for.
Output dari loop dapat dialihkan dari stdout ke file atau ke tempat lain (Anda dapat mempelajari lebih lanjut tentang ini dengan melihat pengalihan I/O).<список>
Sintaksis:
<выполняемые команды>
untuk var di

Mengerjakan
Selesai
Sintaksis:
Contoh:
untuk var di

untuk nama dalam nama1 nama2 nama3 nama4 gema $nama Operator lingkaran<приращение счётчиков>nilai penghitung variabel kita harus selalu berubah (tidak harus naik) sehingga ketika memeriksa kondisi, cepat atau lambat kita mendapatkan nilai salah, jika tidak, loop tidak akan pernah berakhir. Opsi yang sangat nyaman dan, yang paling penting, familier jika operasi apa pun perlu diulang beberapa kali.

Dengan sintaks serupa:
untuk ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
Sintaksis:
<выполняемые команды>
untuk var di

Mengerjakan
untuk ((var=1; var<= LIMIT ; var++))
Sintaksis:
gema $var
untuk var di

perulangan sementara:

Ini adalah konstruksi yang cukup sederhana yang memeriksa kondisi di belakang operator ketika dan jika kondisi ini benar, ia akan mengeksekusi blok perintah yang terletak di antara kata lakukan dan selesai, lalu melanjutkan lagi untuk memeriksa kondisi tersebut. Jika pemeriksaan menghasilkan false, siklus berakhir dan perintah berikut mulai dijalankan: Selesai. Sangat penting untuk memastikan hal itu<проверка условия>bergantung pada kode yang berjalan dalam loop; jika tidak, jika hasil pemeriksaan tidak berubah, Anda akan mendapatkan loop tak terbatas.
Perangkat input standar untuk loop while dapat dialihkan ke file menggunakan perintah pengalihan< в конце цикла.

Saat membuat daftar argumen, Anda dapat menggunakan substitusi perintah dalam perulangan for.
ketika<Проверка условия>
Sintaksis:
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
untuk var di

Mengerjakan
sementara [ $var0 -eq 100 ]
Sintaksis:
gema $var
var++
untuk var di

Operator ketika mungkin memiliki beberapa kondisi. Tetapi hanya yang terakhir yang menentukan kemungkinan melanjutkan siklus tersebut. Dalam hal ini, sintaks operator loop akan berbeda dari biasanya.
Sintaksis(Saya ulangi sekali lagi bahwa hanya kondisi terakhir yang mempengaruhi eksekusi loop) :
ketika
<условие1>
<условие2>

<условиеN>
Sintaksis:
<выполняемые команды - тело цикла>
untuk var di

Sampai loop:

Operator sampai sangat mirip dengan while, ia juga mengevaluasi kondisi, tetapi mengeksekusi badan perulangan jika hasil perhitungannya salah. Ini mungkin tampak tidak biasa, tetapi sampai mengevaluasi kondisi sebelum putaran pertama dari perulangan, seperti while, dan bukan setelahnya. Seperti halnya perulangan for/in, ketika menempatkan kata kunci do pada baris yang sama dengan deklarasi perulangan, Anda harus menyisipkan karakter ";". sebelum melakukan.
Seperti pada kasus sebelumnya, penting untuk diingat bahwa kondisi harus bergantung pada operasi di badan perulangan, jika tidak, skrip kita tidak akan pernah selesai.

Saat membuat daftar argumen, Anda dapat menggunakan substitusi perintah dalam perulangan for.
sampai<Проверка условия>
Sintaksis:
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
untuk var di

Mengerjakan
sampai [ $var0 -gt 100] # Kondisi diperiksa pada awal iterasi.
Sintaksis:
gema $var
var--
untuk var di

Itu mungkin cukup untuk saat ini. :)

  • Kembali
  • Maju

Artikel Baru:

  • Penemuan jaringan tidak menyala di Windows 7/8/2008/2012
  • Kesalahan: Aplikasi ini gagal dijalankan karena tidak dapat menemukan atau memuat plugin platform Qt "windows".
  • Mengonfigurasi restart otomatis proses pekerja rphost.exe di server 1C 8.3
  • Cara memperkecil ukuran log transaksi (.ldf) di MS SQL 2008/20012

    MS SQL, seperti DBMS industri lainnya, bersama dengan database, menyimpan log transaksi yang memungkinkan Anda mengembalikan status...

0 Meeran Bala-Kumaran

Saya benar-benar mencoba memahami mengapa loop sementara ini tidak pernah berakhir, ketika loop dimulai, variabel LOC saya disetel ke Testing/ yang merupakan direktori yang saya buat untuk menguji program ini memiliki tata letak berikut:

Saya ingin loop berakhir setelah semua Direktori menerapkan fungsi "hitungan".
Inilah yang saya coba;

Saya memeriksa fungsi hitungan dan tidak membuat loop tak terbatas

Saya mencoba menjalankan algoritma secara manual

PARSE=1 LOC=$LOC/ count AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") while [ $PARSE = "1" ] lakukan jika [[ $(TERSEDIADIR[@]) == "" ]]; lalu PARSE=0 fi DIRBASE=$LOC untuk a di $(AVAILABLEDIR[@]); lakukan LOC="$(DIRBASE)$(a)" LOCLIST="$LOCLIST $LOC" menghitung selesai untuk a di $(LOCLIST[@]); lakukan TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 hari" | grep "/$" | awk "( print $9 )") PREPEND=$a if [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; lalu lanjutkan fi untuk a di $(TMPAVAILABLEDIR[@]); lakukan TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)" selesai NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" selesai AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" selesai

Saya benar-benar kesulitan dan masukan apa pun akan sangat dihargai, saya telah mencoba memikirkan hal ini selama dua jam terakhir.

bash loop tak terbatas

4 jawaban

Anda harus mencoba menjalankan skrip dengan argumen -x atau menuliskannya di baris pertama:

#!/bin/bash -x

Lalu dia memberitahumu semua yang dia lakukan.

Dalam hal ini, Anda mungkin melihat dua kesalahan:

    Anda tidak pernah memuat ulang TMPAVAILABLEDIR2

    Anda juga melakukan ls pada file biasa.

Jika Anda benar-benar harus menghindari rekursi, coba ini, sepenuhnya tanpa rekursi:

#!/bin/bash count() ( echo menghitung "$1" ) todo=(Pengujian) saat menguji $(#todo[@]) != 0 do doit=("$(todo[@])") todo= () untuk dir di "$(doit[@])" do untuk entri di "$dir"/* # jika dir kosong, ini menunjukkan entri bernama "*" do test -e "$entry" || lanjutkan # lewati entri "*" dari direktori kosong count "$entry" test -d "$entry" || lanjutkan tugas+=("$entry") selesai selesai selesai

Namun, tolong beri tahu saya mengapa Anda tidak bisa menggunakan rekursi? Apakah ini semacam alergi? Sumpah? Apakah ada undang-undang setempat yang melarang perangkat lunak rekursif di tempat Anda tinggal?

Anda menulis bahwa Anda ingin melakukan "penghitungan" pada semua pemotongan. Lihat opsi pencarian:

Temukan $LOC -tipe d | sambil membaca direktori; lakukan cd $LOC cd $(dir) hitungan selesai

atau lebih pendek (ketika penghitung fungsi Anda mengambil direktori sebagai parameter 1)

Temukan $LOC -tipe d | jumlah xarg

Sekarang saya melihat Anda tidak ingin menggunakan find atau ls -R (fungsi rekursif). Maka Anda harus membuat fungsi rekursif Anda sendiri seperti

Fungsi parseDir ( ls -d */ $1 | sambil membaca dir; hitung parseDir $1/$dir selesai )

Saya tidak tahu apakah ini akan berhasil, tetapi ini adalah pertanyaan menarik yang tidak dapat berhenti saya pikirkan. Semoga beruntung

Meskipun benar; lakukan untuk kata di "$(echo *)" ; lakukan jika [[ -d "$kata" ]] ; lalu d[$((i++))]="$PWD"/"$word" elif [[ -f "$word" ]] ;lalu f[$((j++))]="$PWD"/"$ kata" fi selesai [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || istirahat selesai



 


Membaca:



Teknologi Thunderbolt: cara kerjanya dan apa kelebihannya

Teknologi Thunderbolt: cara kerjanya dan apa kelebihannya

Saya rasa hampir semua dari Anda tahu bahwa ada antarmuka seperti Thunderbolt 3 (TB3). Ini adalah versi terbaru dari Thunderbolt. TBC versi pertama...

Cara menaikkan TIC dan PR Cara menaikkan Yandex TIC sendiri

Cara menaikkan TIC dan PR Cara menaikkan Yandex TIC sendiri

TIC adalah Indeks Kutipan Situs tematik. Singkatan ini akrab bagi banyak orang, sering digunakan oleh para webmaster dan Internet -...

Kernel versi 3.10. Mem-flash kernel perangkat Android. Apa inti dari perangkat seluler?

Kernel versi 3.10.  Mem-flash kernel perangkat Android.  Apa inti dari perangkat seluler?

Pada Minggu malam, Linus Torvalds, induk Linux dan pengembang kernel sistem operasi, mengumumkan setelah dua bulan bekerja...

Memulihkan menggunakan disk instalasi

Memulihkan menggunakan disk instalasi

Halo admin. Pertanyaannya adalah ini. Windows 8 saya berumur dua tahun dan saya ingin mengatakan bahwa selama ini saya telah aktif menggunakannya dan menginstal sejumlah besar...

gambar umpan RSS