Bash Əsasları: Döngələr. Bu bölmədə siz for, while və until loopları haqqında öyrənəcəksiniz. Boolean və while loopları bash-də

Döngülər hər hansı bir proqram və ya skript yazarkən son dərəcə əlverişli bir şeydir, daha doğrusu zəruridir. Onlar bizə müəyyən sayda kod parçasını icra etməyə imkan verir. Təbii ki, bash bir neçə növ döngəyə malikdir. Dövrləri təsvir edəcəyik üçün, üçün, müddət, qədər. for və for eyni ifadə üçün müxtəlif sintaksislər hesab edilsə də, mənim fikrimcə, onlar bir-birindən while-dan daha çox fərqlənirlər.

Daxil üçün sayğac ilə döngə:

Velosiped üçün bu sayğaclı bir döngədir. Döngənin gövdəsində yerləşən kod bloku for in operatorunun siyahısında nə qədər dəyər varsa, o qədər təkrarlanır, halbuki hər təkrarda sayğac dəyişəni (burada ona var deyilir, lakin əlbəttə ki, onu istədiyiniz kimi adlandırın) siyahının növbəti elementinin dəyərinə malikdir.
Əgər açar söz do for sözü ilə eyni sətirdədir, onda arqumentlər siyahısından sonra (dodan əvvəl) nöqtəli vergül qoymalısınız.
Elementlərin hər biri<список>çoxlu arqumentlərdən ibarət ola bilər. Bu parametr qruplarını emal edərkən faydalıdır. Bu vəziyyətdə, arqumentlərin hər birini təhlil etməyə məcbur etmək<списке>, siz set ifadəsindən istifadə etməlisiniz
Siz dəyişəni for döngəsində siyahı kimi istifadə edə bilərsiniz.
IN<списке>döngələr üçün fayl adlarından istifadə edilə bilər ki, bu da öz növbəsində joker simvolları ehtiva edə bilər. Bu, çox sayda fayl ilə işləyərkən çox faydalı ola bilər.
Əgər<список>for loopunda göstərilməyib, onda $@ dəyişəni onun kimi istifadə olunur - komanda xətti arqumentlərinin siyahısı.
Arqumentlər siyahısını yaradarkən, for döngəsində əmr əvəzindən istifadə edilə bilər.
Döngənin çıxışı stdout-dan fayla və ya başqa yerə yönləndirilə bilər (bu barədə I/O yönləndirməsini təhlil etməklə daha çox öyrənə bilərsiniz).

Sintaksis:
var üçün<список>
et
<выполняемые команды>
edildi

Misal:
ad1 ad2 ad3 ad4-dəki adlar üçün
et
echo $adları
edildi

Döngə bəyanatı üçün başqa yazı tərzinə malikdir - C dilində for operatorunun sintaksisinə çox bənzəyir.Bu halda sayğacları işə salarkən, ilkin dəyərlər dəyişənlər və ya bir dəyişən və dövrənin hər keçidindən sonra şərt yoxlanılır, əgər yoxlama doğrudursa, onda dövrənin növbəti keçidi başlayır. Blokda<приращение счётчиков>dəyişən sayğaclarımızın dəyəri mütləq dəyişməlidir (yuxarıya doğru deyil) belə ki, şərti yoxlayanda gec-tez yalanların qiymətini alırıq, əks halda dövrə heç vaxt bitməyəcək. Hər hansı bir əməliyyatın müəyyən bir neçə dəfə təkrarlanması lazımdırsa, çox rahat və ən əsası tanış seçim.

Bənzər sintaksis ilə:
üçün ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
et
<выполняемые команды>
edildi

Misal:
üçün ((var=1; var<= LIMIT ; var++))
et
echo $var
edildi

while döngüsü:

Bu, operatorun arxasındakı vəziyyəti yoxlayan kifayət qədər sadə bir tikintidir isə və əgər bu şərt doğrudursa, o, do və görülən sözləri arasında yerləşən əmrlər blokunu yerinə yetirir və sonra yenidən şərti yoxlamağa davam edir. Çek yalnış qaytararsa, dövrə başa çatır və aşağıdakı əmrlər yerinə yetirilir: edildi. Bunu təmin etmək lazımdır<проверка условия>döngədə işləyən koddan asılıdır, əks halda yoxlamanın nəticəsi dəyişməzsə, sonsuz bir döngə əldə edəcəksiniz.
Bir müddət dövrə üçün standart giriş, yönləndirmə əmrindən istifadə edərək fayla yönləndirilə bilər< в конце цикла.

Sintaksis:
isə<Проверка условия>
et
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
edildi

Misal:
isə [ $var0 -ekv 100 ]
et
echo $var
var++
edildi

Operator isə bir neçə şərt ola bilər. Ancaq onlardan yalnız sonuncusu dövrü davam etdirmək imkanını müəyyən edir. Bu halda, loop ifadəsinin sintaksisi adi olandan fərqli olacaq.
Sintaksis(Bir daha təkrar edirəm ki, döngənin icrasına yalnız sonuncu şərt təsir edir) :
isə
<условие1>
<условие2>

<условиеN>
et
<выполняемые команды - тело цикла>
edildi

dönənə qədər:

Operator qədər while-a çox bənzəyir, o, həm də şərti qiymətləndirir, lakin hesablamanın nəticəsi yalan olarsa, dövrənin gövdəsini yerinə yetirir. Qəribə görünə bilər, amma dövrənin ilk təkrarlanmasından əvvəlki vəziyyəti qiymətləndirənə qədər, məsələn, while kimi, ondan sonra deyil. for/in döngələrində olduğu kimi, do açar sözünü döngə bəyannaməsi ilə eyni sətirdə yerləşdirərkən ";" simvolunu daxil etməlisiniz. etməzdən əvvəl.
Əvvəlki halda olduğu kimi, yadda saxlamaq lazımdır ki, şərt loop gövdəsindəki əməliyyatlardan asılı olmalıdır, əks halda skriptimiz heç vaxt bitməyəcək.

Sintaksis:
qədər<Проверка условия>
et
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
edildi

Misal:
[ $var0 -gt 100] qədər # Şərt iterasiyanın əvvəlində yoxlanılır.
et
echo $var
var--
edildi

Yəqin ki, hələlik kifayətdir. :)

  • Geri
  • İrəli

Yeni məqalələr:

  • Şəbəkə kəşfi Windows 7/8/2008/2012-də açılmır
  • Xəta: Bu proqram "windows" Qt platforma plaqini tapa bilmədiyi və ya yükləyə bilmədiyi üçün başlaya bilmədi.
  • İş proseslərinin avtomatik yenidən başlamasının konfiqurasiyası rphost.exe server 1C 8.3
  • MS SQL 2008/20012-də əməliyyat jurnalının (.ldf) ölçüsünü necə azaltmaq olar

    MS SQL, hər hansı layiqli sənaye DBMS kimi, verilənlər bazası ilə birlikdə, vəziyyəti geri qaytarmağa imkan verən əməliyyat qeydlərini saxlayır ...

BASH əsasları. 2-ci hissə.
Məqalələr arasında belə uzun gecikmə üçün üzr istəyirəm, lakin sessiya özünü ən uyğun olmayan anda hiss etdirir :)
Sonuncu məqaləyə şərhlərdə səslənən şərhlər, tənqidlər və əlavələr üçün hamınıza təşəkkür edirəm.
Bu hissə, söz verildiyi kimi, döngələrə, riyazi əməliyyatlara və xarici əmrlərin istifadəsinə həsr olunacaq.
Gəlin başlayaq.

dövrələr. for-in loop.

For-in operatoru siyahıda sadalanan dəyərlərə bir-bir daxil olmaq üçün nəzərdə tutulmuşdur. Siyahıdakı hər bir dəyər öz növbəsində dəyişənə təyin edilir.
Sintaksis aşağıdakı kimidir:
dəyər_siyahısındakı dəyişən üçün
et
əmrlər
edildi

Kiçik bir nümunəyə nəzər salın:

#!/bin/bash
i in 0 1 2 3 4 #dəyişən $i üçün 0-dan 4-ə qədər qiymətlər təyin ediləcək
et
echo "Konsol nömrəsi $i" >> /dev/pts/$i # /dev/pts/$i faylına "Konsol nömrəsi $i" sətrini yazın
bitdi #dövrü bitdi
0-dan çıxın

Nümunəni yerinə yetirdikdən sonra ilk 5 virtual konsolda (terminallarda) onun nömrəsi ilə bir xətt görünəcəkdir. Siyahıdakı dəyərlər növbə ilə $i dəyişəni ilə əvəz olunur və bu dəyişənin dəyəri ilə iş bir döngədə aparılır.

dövrələr. while loop.

while döngəsi for-in döngəsindən daha mürəkkəbdir və bəzi ifadələr doğru olduqda əmrləri təkrarlamaq üçün istifadə olunur (qaytarma kodu = 0).
Operatorun sintaksisi aşağıdakı kimidir:
isə ifadə və ya qaytarma kodunu qaytaran əmr
et
komandalar
edildi

Döngənin necə işlədiyinə dair bir nümunə aşağıdakı nümunədə göstərilmişdir:

#!/bin/bash
again=yes #dəyişənə yenidən "bəli" dəyərini təyin edin
while [ "$ain" = "yes" ] #Biz $ain "bəli"yə bərabər olana qədər dönəcəyik
et
echo "Zəhmət olmasa ad daxil edin:"
adını oxu
echo "Daxil etdiyiniz ad $namedir"

Echo "Davam etmək istəyirsiniz?"
yenidən oxu
edildi
echo "Bye-Bye"


İndi skriptin nəticəsi:
[email protected]:~$ ./bash2_primer1.sh
Zəhmət olmasa ad daxil edin:
ite
Daxil etdiyiniz ad itdir
Davam etmək istəyirsiniz?
bəli
Zəhmət olmasa ad daxil edin:
Michael
Daxil etdiyiniz ad mihaildir
Davam etmək istəyirsiniz?
yox
sağ ol

Gördüyünüz kimi, döngə "bəli"dən başqa bir şey daxil edənə qədər icra olunur. Do və görülən arasında istənilən strukturları, ifadələri və s. təsvir edə bilərsiniz, onların hamısı bir dövrədə yerinə yetiriləcək.Lakin bu dövrə ilə diqqətli olmalısınız, əgər ifadə dəyişənini dəyişmədən orada hər hansı bir əmr işlədirsinizsə, əldə edə bilərsiniz. sonsuz bir döngəyə.
İndi həqiqət şərtinə. Bir müddətdən sonra, if-then-else şərti ifadəsində olduğu kimi, siz qaytarma kodunu qaytaran istənilən ifadə və ya əmri daxil edə bilərsiniz və dönmə kodu = 0 olduğu müddətcə icra ediləcək! “[” operatoru ona verilən şərtin doğruluğunu yoxlayan test əmrinin analoqudur.

Başqa bir nümunəyə baxaq, mən onu Advanced Bash Scripting kitabından götürdüm. Çox bəyəndim :), amma bir az sadələşdirdim. Bu nümunədə biz UNTIL-DO döngələrinin başqa bir növü ilə tanış olacağıq.. Bu, demək olar ki, WHILE-DO dövrəsinin tam analoqudur, yalnız bəzi ifadələr yalan olduqda yerinə yetirilir.
Budur bir nümunə:

#!/bin/bash
echo "Sayı daxil edin:"
dividend oxuyun
echo "Məhrəci daxil edin:"
bölən oxu

dnd=$dividend #dividend və bölən dəyişənləri dəyişdirəcəyik,
#biliklərini başqa dəyişənlərdə saxla, çünki bizə verirlər
#lazımdır
dvs=$bölən
qalıq=1

[ "$qalan" -eq 0 ] qədər
et
qoy "qalıq = dividend % bölən"
dividend=$bölən
bölən = $qalıq
edildi

Echo "$dnd və $dvs ədədlərinin gcd = $dividend"


Skriptin icrasının nəticəsi:
[email protected]:~$ ./bash2_primer3.sh
Sayıcı daxil edin:
100
Məxrəci daxil edin:
90
100 və 90 rəqəmlərinin GCD = 10

Riyazi əməliyyatlar

əmr etsin.
let əmri ədədlər və dəyişənlər üzərində arifmetik əməliyyatlar yerinə yetirir.
Daxil edilmiş nömrələr üzərində bəzi hesablamalar apardığımız kiçik bir nümunəyə nəzər salın:
#!/bin/bash
echo "Daxil edin:"
oxumaq a
əks-səda "b daxil edin:"
oxumaq b

"c = a + b" #əlavə edək
əks-səda "a+b= $c"
qoy "c = a / b" #bölün
əks-səda "a/b= $c"
qoy "c<<= 2" #сдвигает c на 2 разряда влево
echo "c 2 bit sürüşdükdən sonra: $c"
qoy "c = a % b" # a b-yə bölündükdə qalığı tapsın
echo "$a / $b. qalıq: $c "


İcra nəticəsi:
[email protected]:~$ ./bash2_primer2.sh
Daxil edin:
123
b daxil edin:
12
a+b=135
a/b=10
c 2 bit sürüşdürdükdən sonra: 40
123 / 12. qalıq: 3

Gördüyünüz kimi, mürəkkəb bir şey yoxdur, riyazi əməliyyatların siyahısı standartdır:
+ - əlavə
- - çıxma
* - vurma
/ - bölmə
** - eksponentasiya
% - modul(modul bölgüsü), bölmənin qalığı
let arifmetik əmrlər üçün abreviaturalardan istifadə etməyə imkan verir və bununla da istifadə olunan dəyişənlərin sayını azaldır. Məsələn: a = a+b a +=b ilə bərabərdir və s.

Shell skriptləri yazarkən xarici proqramlarla işləmək

Bəzi faydalı nəzəriyyə ilə başlayaq.
Yayımın yönləndirilməsi.
Bash (və bir çox digər qabıqlar) daxili fayl deskriptorlarına malikdir: 0 (stdin), 1 (stdout), 2 (stderr).
stdout - Standart çıxış. Proqramların çıxardığı hər şey bura gedir.
stdin - Standart giriş. İstifadəçinin konsolda yazdıqları bütün bunlardır
stderr - Standart səhv çıxışı.
Bu deskriptorlar üzərində əməliyyatlar üçün xüsusi simvollar var: > (çıxışın yönləndirilməsi),< (перенаправление ввода). Оперировать ими не сложно. Например:
cat /dev/random əmrinin çıxışını /dev/null-a yönləndirin (tamamilə faydasız əməliyyat :))) və ya
cari kataloqun məzmununu siyahı faylına yazın (artıq daha faydalıdır)
Fayla əlavə etmək zərurəti yaranarsa (">" istifadə etdikdə o əvəzlənir), ">" əvəzinə ">>" istifadə etməlisiniz.
sudo-dan parolu daxil etməyi xahiş etdikdən sonra o, sanki klaviaturadan daxil etmiş kimi my_password faylından götürüləcək.
Fayla yalnız proqramın işləməsi zamanı baş verə biləcək səhvləri yazmaq lazımdırsa, o zaman istifadə edə bilərsiniz:
./program_with_error 2> error_file
">" işarəsindən əvvəl 2 rəqəmi o deməkdir ki, 2-ci deskriptora (stderr) daxil olan hər şey yönləndirilməlidir.
Əgər stderr-i stdout-a yazmağa məcbur etmək lazımdırsa, bunu aşağıdakı kimi etmək olar. yol:
"&" simvolu deskriptor 1 (stdout) üçün göstərici deməkdir
(Standart olaraq, stderr istifadəçinin işlədiyi konsola yazır (displeyə yazma ehtimalı daha yüksəkdir)).
2. Konveyerlər.
Boru kəməri Bash konsolu ilə işləmək üçün çox güclü bir vasitədir. Sintaksis sadədir:
komanda1 | komanda 2 - 1-ci əmrin çıxışının 2-ci əmrin girişinə ötürüləcəyini bildirir
Boru kəmərləri fayla yönləndirmədən istifadə edərək zəncirlərə və çıxışlara qruplaşdırıla bilər, məsələn:
ls -la | grep "hash" |sort > sortilg_list
ls -la əmrinin çıxışı hash sözünü ehtiva edən bütün sətirləri seçən grep əmrinə ötürülür və nəticəni faylın sıralama_siyahısına yazan sort əmrinə ötürülür. Hər şey olduqca aydın və sadədir.

Çox vaxt, Bash skriptləri konsolda bəzi adi əməliyyatların avtomatlaşdırılması kimi istifadə olunur, buna görə də bəzən bir əmrin stdout-unu emal etmək və onu stdin-ə digər komandaya köçürmək lazım olur, bir əmrin icrasının nəticəsi isə emal edilməlidir. bir şəkildə. Bu bölmədə işləməyin əsas prinsiplərini izah etməyə çalışacağam xarici komandalar skript daxilində. Düşünürəm ki, kifayət qədər misal gətirmişəm və indi yalnız əsas məqamları yaza bilərəm.

1. Çıxışın dəyişənə ötürülməsi.
Komandanın çıxışını dəyişənə yazmaq üçün əmri məsələn, `` dırnaqlara daxil etmək kifayətdir.
a = `echo "qwerty"`
echo $a

İşin nəticəsi: qwerty


Bununla belə, dəyişənə qovluqların siyahısını yazmaq istəyirsinizsə, verilənləri dəyişənə yerləşdirmək üçün nəticəni düzgün emal etməlisiniz. Kiçik bir nümunəyə nəzər salaq:
LIST=`tap /svn/ -tip d 2>/dev/null| awk "(FS="/") ($4 çap edin)"| sort|uniq| tr "\n" " "`
$LIST-də ONE_OF_LIST üçün
et
svnadmin hotcopy /svn/$ONE_OF_LIST /svn/temp4backup/$ONE_OF_LIST
edildi

Burada svnadmin hotcopy əmrindən istifadə etməklə /svn/ qovluğundakı bütün qovluqları arxivləşdirmək üçün for-do-done dövrəsindən istifadə edirik (bunun bizim vəziyyətimizdə heç kimə əhəmiyyəti yoxdur, misal kimi). Ən maraqlı sətir: LIST=`find /svn/ -type d 2>/dev/null| awk "(FS="/") ($4 çap edin)"| sort|uniq| tr "\n" " "` Orada LIST dəyişəninə icra təyin olunur əmrləri tapın, awk, sort, uniq, tr əmrləri ilə işlənir (biz bütün bu əmrləri nəzərdən keçirməyəcəyik, çünki bu ayrıca məqalədir). SİYAHI dəyişəni bir sətirdə yerləşdirilmiş /svn/ qovluğundakı bütün qovluqların adlarını ehtiva edəcək (dövrəni boşaltmaq üçün.

Gördüyünüz kimi, hər şey çətin deyil, prinsipi başa düşmək və bir neçə öz skriptinizi yazmaq kifayətdir. Sonda sizə BASH və ümumilikdə Linux-u öyrənməkdə uğurlar arzulamaq istəyirəm. Tənqid, həmişə olduğu kimi, xoşdur. Növbəti məqalə yəqin ki, sed, awk kimi proqramların istifadəsinə həsr olunacaq.

Əsas qaydalardan biri sistem idarəsi belə qoymaq olar: eyni şeyi tez-tez etmək lazımdırsa, bir ssenari yazın və onun sizin üçün iş görməsinə icazə verin. Bir neçə dəfə skript daxilində bəzi hərəkətləri yerinə yetirmək lazımdırsa, istifadə etməlisiniz dövrələr. IN GNU Bash konstruksiyalarla ilmələr yarada bilərsiniz üçün, isəqədər.

Əgər nə vaxtsa proqramlaşdırma ilə maraqlanmısınızsa, ehtimal ki, bu konstruksiyalarla artıq tanışsınız. Əgər mənim kimi oxuyursansa bash Arxanızda heç bir proqramlaşdırma təcrübəniz yoxdursa, döngələrin istifadəsi başa düşmək üçün kifayət qədər aydın olmaya bilər. Aralarındakı fərqləri müəyyən etməklə başlayaq müxtəlif növlər dövrlər, sonra nümunələrə keçin.

Velosiped üçün hamısı tamamlanana qədər hərəkətləri təkrarlamaq üçün nəzərdə tutulmuşdur. Məsələn, təsəvvür edin ki, sizin şəkillər kataloqunuz var və onları bir formatdan digərinə çevirməlisiniz. Bir döngə istifadə edə bilərsiniz üçün proqramı ilə birlikdə çevirmək paketdən ImageMagick(və ya başqa bir proqram), məsələn, şəkilləri çevirmək üçün JPEG formatı PNG formatına. Və ya, məsələn, bir çox səs faylını çevirmək lazım ola bilər MP3 V OGG Vorbis.

Velosiped isə hərəkətləri təkrarlamaq üçün istifadə olunur sağol həyata keçirilir (dir doğru) bəzi şərt. Velosiped qədər bir az fərqli işləyir: bir hərəkəti yerinə yetirir qədərşərt yerinə yetirilənə qədər. Beləliklə, məsələn, bir hərəkətə qarşı çıxa və yerinə yetirə bilərsiniz qədər dəyəri 10-a çatana qədər. Buna misallarla daha ətraflı baxaq.

Bir döngə ilə başlayaq üçün. Onun formatı belədir:

i üçün $(komanda); $i əmrini yerinə yetirin; edildi

Bir döngə istifadə edirsinizsə üçün skriptdə onu belə formatlaşdırmaq daha yaxşıdır:

#!/bin/bash for i for $(command); $ əmrini yerinə yetirdim

Beləliklə, məsələn, etmək lazımdırsa ehtiyat nüsxələri qovluqdakı bütün HTML faylları üçün aşağıdakı əmrdən istifadə edə bilərsiniz:

i üçün $(ls *html); cp $i $i.bak etmək; edildi

Bu, yerli dəyişən yaradır $i, əmr yerinə yetirilir ls*html, nəticələri dəyişənin dəyərini başlatan məlumatlar olacaq $i döngənin hər iterasiyasında (bizim nümunəmizdə bu əmrlə qaytarılan faylların siyahısı olacaq ls, hər iterasiya üçün bir). Sonra, əmr yerinə yetirilir cp, parametrlər arasında dəyişən ötürülür $i.

Kimsə məktubun istifadəsinin məcburi olub olmadığını soruşa bilər "mən" dəyişən adı kimi? Yox. İstənilən etibarlı istifadə edə bilərsiniz bash dəyişən adı. Təbii ki, skriptlərdə daha mənalı dəyişən adlarından istifadə etmək daha yaxşıdır, məsələn $input və ya $html.

Döngədən istifadə etmək üçün çox qısa və sadə bir nümunə verdim üçün. Blokda yerinə yetirilən əmr əvəzinə et,istifadə edin əks-səda ona keçilən parametrləri görmək üçün. Bu, skriptlərin sınaqdan keçirilməsi mərhələsində çox faydalı bir təcrübədir yaxşı yol işinizi daha ətraflı başa düşməyə kömək edir üçün.

zamanı və qədər

İndi konstruksiyaları nəzərdən keçirin isəqədər. Həmçinin, biz bash şərtlərindən bir qədər istifadə edəcəyik. Nümunəmizdə onlardan, məsələn, dəyişənin dəyərinin X rəqəmindən böyük və ya kiçik olduğunu müəyyən etmək üçün istifadə edəcəyik; faylın mövcud olub-olmaması və qovluq olub-olmaması. Siz həmçinin, məsələn, faylın oxunaqlı olub olmadığını və ya icazələrində GID bitinin olub-olmadığını müəyyən etmək üçün şərtlərdən istifadə edə bilərsiniz.

Bəzi boş fayllar yaratmaq kimi sadə bir şey etməyə çalışaq. Həyatda bu, çətin ki, sizin üçün faydalı olsun, amma misal olaraq, elə budur.

#!/bin/bash i=0 [ $i -lt 22 ] $i i=$[$i+1] yerinə toxunduqda

Bu skript 0-dan 21-ə qədər adları olan 22 fayl yaradacaq. Döngü bu vaxta qədər davam edəcək sağol dəyişən dəyər $i az ( -lt) 22.

İndi yaradılan faylları bir döngə ilə qurtaraq qədər:

#!/bin/bash i=0 [ $i -eq 22 ] rm $i i=$[$i+1] tamamlanana qədər

Burada əvəz etdik isə haqqında qədər, şərti ifadədə isə əvəz etdik "az" (-lt) açıqdır "bərabərdir" (-eq). Beləliklə, skriptimiz dəyər olduğu müddətcə işləyəcək $i 22 çatmayacaq. Və yerinə toxun istifadə etdik rm faylları yaratmaq əvəzinə onları silmək. Sadə, elə deyilmi?

üçün VAR in 1 2 3...N et edildi və ya bir sətirdə: üçün VAR in 1 2 3...N; et ; edildi
Həm rəqəmli dəyərləri, həm də ASCII simvollarını dəyişənə əvəz etməyə icazə verilir.
Misal: $ i in 1 2 A B Abc ; echo $i etmək; görüldü 1 2 A B Abc Videonun transkodlanması üçün faylların "maska" ilə dəyişənə ötürülməsinə nümunə: üçün i in*.avi; et ; edildi

2. Başqa bir əmrin icrasının nəticələrinin əvəz edilməsi

üçün VAR in $(); et ; edildi
Seq əmrinin nəticələrindən istifadə nümunəsi: üçün i in$(seq[KEY]); et echo $i; edildi$-da i üçün $(seq 3); echo $i etmək; $-da i üçün 1 2 3 $ yerinə yetirildi (seq 3 5); echo $i etmək; $-da i üçün 3 4 5 $ yerinə yetirildi (seq 2 2 6); echo $i etmək; görüldü 2 4 6 ls əmrinin nəticələrindən istifadə nümunəsi: $ for i in $(ls /$HOME/Video); echo $i etmək; edildi 001.avi 002.avi 003.avi

3. C üslubundan istifadə edərək əvəzetmə

üçün((EXPR1; EXPR2; EXPR3)) et <список команд> edildi üçün((i=1; i<=3 ; i++)); et echo $i; edildi$ üçün ((i=1; i<=3 ; i++)); do echo $i; done 1 2 3 Подробнее о применении C-style в Bash

4. Buruq mötərizələrlə sadalama (..)

Sintaksis (START..END) bash 3.0+ versiyasından bəri dəstəklənir və bash 4.0+ versiyasından bəri sintaksis (START..END..INCREMENT) dəstəklənir:

üçün VAR in {..} et edildi və ya üçün VAR in {....} et edildi Nümunələr: i üçün $ (1..3); echo $i etmək; i üçün 1 2 3 və ya $ yerinə yetirildi (4..8..2); echo $i etmək; yerinə yetirildi 4 6 8 Qiymətlərin həm artırılması, həm də azalması üçün hesablama mümkündür: i üçün $ (6..-4..3); echo $i etmək; 6 3 0 -3 yerinə yetirildi

5. Parametrlərin dəyişdirilməsi ( in "$@")

Skriptə ötürülən hər bir parametr üçün əmrləri yerinə yetirir. üçün VAR in $@ et edildi və ya bir sətirdə: üçün VAR in $@; et ; edildi
Beləliklə, bir test.sh skripti yaratsanız #!/bin/sh üçün VAR in $@ et əks-səda$var edildi sonra onu parametrlərlə işləyərkən: $ ./test.sh param1 param2 param3 param1 param2 param3 Hissə in$@ buraxıla bilər. Sonra test.sh skripti yenidən yazılacaq: #!/bin/sh üçün VAR et əks-səda$var edildi
Budur bir neçə nümunə (ile in və olmadan): $ FUNC_1 (VAR üçün $@; echo $VAR; yerinə yetirildi; ) $ FUNC_1 param1 param2 param3 param1 param2 param3 $ funksiya FUNC_2 (VAR üçün; echo $VAR; yerinə yetirildi; ) $ FUNC_2 param1 param2 param3 param1 param2 param3

6. Davam və fasilə tətbiqi for döngəsində

Yuxarıda göstərilən bütün konstruksiyalar üçün döngənin növbəti elementinə keçmək üçün "davam et" əmrlərindən istifadə etmək və ya döngədən çıxmaq üçün "break" etmək mümkündür.

Nümunə (i=6 olduqda dayandırın və i=3 və i=5 olduqda icra etməyin): üçün i in(1..8); et əgər[ $i -ekv 6 ]; sonra fasilə; fi əgər[ $i -eq 3 ] || [ $i -ekv 5 ]; sonra davam etdirmək; fi echo $i edildiİcra nəticəsi: i üçün $ $ (1..8); do \ > if [ $i -eq 6 ]; sonra qırmaq; fi; \ > əgər [ $i -eq 3 ] || [ $i -ekv 5 ]; sonra davam edin; fi; \ > echo $i; \> 1 2 4 edildi

Döngə növlərindəki fərqin qısa təsviri:

for - yerinə yetiriləcək obyektlər olduğu müddətcə hərəkəti yerinə yetirəcək (məsələn, stdin , fayl və ya funksiyadan axını oxumaq);
while - qədər hərəkəti yerinə yetirir vəziyyət doğrudur;
qədər - qədər icra olunacaq vəziyyət həqiqətə çevrilməyəcək, yəni. yalan olduğu müddətcə.

FOR döngəsi

Döngə ilə skriptin bu versiyasını nəzərdən keçirin:

`ls -1` daxilində dəyişən üçün $ cat loop.sh #!/bin/bash "$dəyişən"in əksini tapdı

Sintaksis çox sadədir və nümunədə olduqca aydın şəkildə göstərilmişdir:

for (dövrəni başladın) dəyişəni (hərəkətləri yerinə yetirmək üçün dəyişəni elan edin) (axını dövrəyə yönəldin) `ls -1` (əmr edilməli və $dəyişən dəyişəninə ötürüləcək əmr). Etmək və yerinə yetirmək dövrün "gövdəsidir" və onun daxilində əsas hərəkətlər qəbul edilmiş məlumatlar üzərində yerinə yetiriləcək və əks-səda "$dəyişən" dövr tərəfindən yerinə yetirilən hərəkətin özüdür.

İndi nümunəni bir az dəyişdirək və əmri açıq şəkildə göstərmək əvəzinə ikinci dəyişəni tətbiq edəcəyik:

$ cat loop.sh #!/bin/bash ls=`ls -1` $ls-də dəyişən üçün "$dəyişən" əksini tapdı

İndi ls -1 əmri ayrıca dəyişəndə ​​ötürülür ki, bu da dövrə ilə daha çevik işləməyə imkan verir. Döngədəki dəyişən əvəzinə bir funksiyadan da istifadə edə bilərsiniz:

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) `lsl`-də dəyişən üçün "$dəyişən" echo edin

For döngəsinin əsas şərti ondan ibarətdir ki, ona verilən əmrdə hərəkət üçün obyektlər olduğu müddətcə icra olunacaq. Yuxarıdakı nümunəyə əsasən - ls -1 siyahısında göstəriləcək fayllar olduğu müddətcə - dövrə onları dəyişənə ötürəcək və "dövrə gövdəsini" icra edəcək. Kataloqdakı faylların siyahısı bitən kimi dövrə öz icrasını tamamlayacaq.

Məsələni bir qədər mürəkkəbləşdirək.

Kataloqda faylların siyahısı var:

$ ls -1 fayl1 fayl2 fayl3 fayl4 fayl5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

Onlardan ancaq sözü olmayanları seçməliyik” yox«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` $lsl-də dəyişən üçün "$dəyişən" echo edin | grep -v "yox" edildi $ ./loop.sh fayl1 fayl2 fayl3 fayl4 fayl5 loop.sh

Döngədə şərti ifadələrdən də istifadə edə bilərsiniz ( şərti ifadələr) […] şərtləri sınamaq və şərt işə salınarsa, döngəni qırmaq üçün fasilə ifadəsini.

Bu misalı nəzərdən keçirək:

$ cat loop.sh #!/bin/bash lsl=`ls -1` $lsl-də dəyişən üçün bunu edin əgər [ $dəyişən != "loop.sh" ] sonra "$dəyişən" echo | grep -v "yox" başqa sındırmaq tamamlandı

Döngə loop.sh faylı ilə qarşılaşana qədər işləyəcək. Döngənin icrası bu fayla çatan kimi fasilə əmri ilə dövrə kəsiləcək:

$ ./loop.sh fayl1 fayl2 fayl3 fayl4 fayl5

Başqa bir misal, döngə gövdəsinin icrasından dərhal əvvəl arifmetik əməliyyatların istifadəsidir:

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

Burada üç idarəetmə əmri təyin etdik - count=1 , nəzarət şərti - count 11-dən az olduqda və yerinə yetirmək üçün əmr - count +1:

WHILE və UNTIL dövrələri

while dövrəsinin necə yaxşı işlədiyini göstərən sadə bir nümunə:

$ cat loop.sh #!/bin/bash count=0 isə [ $count -lt 10 ] do ((count++)) echo $count tamamlandı

Biz $count dəyişənini sıfıra qoyuruq, bundan sonra “while loop” şərti ilə “while loop”u icra edirik “while $count on azdır, loop”. Döngə gövdəsində icra edirik postfiks artımı$count dəyişəninə +1 və nəticəni stdout-a çap edin.

İcra nəticəsi:

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

$count dəyişəninin dəyəri 10 olan kimi dövrə dayandı.

while işlədiyini nümayiş etdirən "sonsuz" döngənin yaxşı nümunəsi:

$ cat loop.sh #!/bin/bash count=10 isə [ 1 = 1 ] do ((count++)) echo $count tamamlandı $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^C

Eynilə, lakin əks istiqamətdə, qədər dövrə də işləyir:

$ cat loop.sh #!/bin/bash count=0 [ $count -gt 10 ] qədər ((count++)) echo $count tamamlandı

Burada oxşar şərt qoyuruq, lakin “dəyişən 10-dan kiçik olana qədər” əvəzinə “dəyişən 10-dan böyük olana qədər” işarəsini veririk. İcra nəticəsi:

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

Yuxarıdakı "sonsuz döngə" nümunəsi qədər istifadə edilərsə, while-dan fərqli olaraq heç bir nəticə verməyəcək:

$ cat loop.sh #!/bin/bash count=10 [ 1 = 1 ] yerinə ((count++)) echo $count yerinə yetirildi $ ./loop.sh $

Çünki " vəziyyət» ilkin « doğru» - döngənin gövdəsi yerinə yetirilməyəcək.

For döngəsində olduğu kimi, funksiyalardan while və qədər istifadə edilə bilər. Məsələn, serverin vəziyyətini yoxlayan həqiqətən istifadə olunan skriptdən bir döngə pişik(PID sistemdə alınır SLES, digər sistemlərdə fərqlənə bilər), bir qədər sadələşdirilmiş versiya:

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(2$ çap edin)"` ) isə check_tomcat_status [ -n "$ olduqda bunu edin. RUN" ] sonra printf "XƏBƏRDARLIQ: Tomcat hələ də PID $RUN ilə işləyir." else printf "Tomcat dayandı, davam edir...nn" fasiləsi tamamlandı

İcra nəticəsi:

$ ./loop.sh XƏBƏRDARLIQ: Tomcat hələ də PID 14435 26548 ilə işləyir. XƏBƏRDARLIQ: Tomcat hələ də PID 14435 26548 ilə işləyir. XƏBƏRDARLIQ: Tomcat hələ də PID 14435 26548 ilə işləyir. XƏBƏRDARLIQ: Tomcat hələ də PID 14435 26548 ilə işləyir. XƏBƏRDARLIQ: Tomcat hələ də PID 14435 26548 ilə işləyir. XƏBƏRDARLIQ: Tomcat hələ də PID 14435 ilə işləyir

Tam versiyası:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(2$ çap edin)"` ) isə check_tomcat_status; edin, əgər [ -n "$RUN" ] sonra printf "XƏBƏRDARLIQ: Tomcat hələ də PID $RUN ilə işləyir. Dayandırılsın? " cavabı "Tomcat dayandırılır..." "Quraşdırılma davam etdirilir..." && $CATALINA_HOME/bin/sutdown. sh 2&>1 /dev/null || yuxunu poz 2 əgər [ -n "$RUN" ] sonra printf "Tomcat hələ də işləyir. Öldürsün? " cavabı "Tomcat öldürülür..." "Quraşdırma davam etdirilir...n" && $RUN || fasilə yuxu 2 fi else printf "Tomcat dayandı, davam edir...nn" fasilə fi tamamlandı

Cavab funksiyası məqalədə təsvir edilmişdir, lakin burada bir qədər təkmilləşdirilmiş versiya istifadə olunur:

Cavab () (cavab oxuyarkən; əks halda $cavab | ilə əks olunsun) printf "$1n" 0 fasilə qaytarın;; |) printf "$2n" 1 fasilə qaytarın;; *) printf "Zəhmət olmasa, Y(bəli) və ya N(xeyr) daxil edin!" esac tamamlandı )

Burada həm while, həm də qədər istifadə etmək mümkün idi - lakin for döngəsindən deyil, çünki for bir dəfə işləyəcək (PID alın - və son).