5. حلقه های شرطی( while و until و for )
تا اینجا آموختهاید چگونه برخی تصمیمگیری های اساسی در اسکریپتهایتان را بسازید. اگر چه، برای انجام همه انواع وظایفی که ممکن است از اسکریپت بخواهیم کافی نمیباشد. گاهی اوقات نیاز به تکرار برخی کارها داریم. برای همین، کاربرد یک حلقه لازم است. دو نوع اصلی ازحلقه( به اضافه نوع دیگری) وجود دارد، و استفاده از نوع صحیح حلقه به شما در نگهداری خوانایی و قابلیت پشتیبانی اسکریپتهایتان کمک میکند.
دو نوع اساسی حلقهها
while command: تا وقتی که command به طور موفقی اجرا میشود(کد خروج صفر است)، تکرار میشود.until command: مادامیکه command به طور ناموفق اجرا گردد(کد خروج صفر نباشد)، تکرار میشود.for variablein words: حلقه برای هر یک از wordsکه به نوبت در متغیر variable قرار میگیرند، تکرار میشود.
for (( expression; expression; expression)) : با اجرای اولین عبارت حسابی شروع میکند، تا موقعیکه ارزیابی دومین عبارت حسابی موفق است حلقه تکرار میشود، و در پایان هر حلقه عبارت حسابی سوم انجام میشود.
هر شکل از حلقهها با کلمهکلیدی
در عمل، حلقهها برای انواع مختلفی از وظایف به کار میروند. حلقه
در اینجا چند مثال برای تشریح تفاوتها و همچنین شباهتهای حلقهها میآوریم. (یادآوری: در اکثر سیستمعاملها، برای کشتن برنامهای که در ترمینال در حال اجرا است از ترکیب کلیدی
$while true >do echo "Infinite loop" >done
$while ! ping-c 1 -W 1 1.1.1.1; do > echo "still waiting for 1.1.1.1" > sleep 1 >done
$(( i =10 ));while (( >i >0 ))do echo "$ i empty cans of beer." >(( >i -- ))done $for (( >i =10 ;i >0 ;i -- ))do echo "$ i empty cans of beer." >done $for i in { 10..1 } >do echo "$ i empty cans of beer." >done
سه حلقه آخری با ترکیب متفاوت، دقیقاً به نتیجه یکسانی میرسند. در تجربه اسکریپتنویسی شل خود بارها با این مورد مواجه میشوید. تقریباً همیشه راهکارهای چندگانهای برای حل یک مسئله موجود است. به زودی تشحیص مهارت شما در حل مسئله نخواهد بود، آنقدر که درچگونگی
بیایید نگاه نزدیکتری به آن مثال آخری داشته باشیم، زیرا اگر چه از دو حلقه
به طوری که قبلاً اشاره کردهام:
$for i in 10 9 8 7 6 5 4 3 2 1 >do echo "$ i empty cans of beer." >done
BASH کاراکترهای بین کلمهکلیدی
در نتیجه،
$ lsThe best song in the world.mp3 $for file in $ (ls* .mp3 ) >do rm "$file" >done rm: cannot remove `The\': No such file or directory rm: cannot remove `best\': No such file or directory rm: cannot remove `song\': No such file or directory rm: cannot remove `in\': No such file or directory rm: cannot remove `the\': No such file or directory rm: cannot remove `world.mp3\': No such file or directory
شما از قبل نسبت به نقلقولی کردن
خواهید گفت، آن را نقلقولی میکنم؟ اجازه دهید فایل دیگری اضافه کنم:
$ lsThe best song in the world.mp3 The worst song in the world.mp3 $for file in "$(ls * .mp3)" >do rm "$ file" >done rm: cannot remove `The best song in the world.mp3 The worst song in the world.mp3\': No such file or directory
نقلقولها به راستی از فضای سفید در نام فایلهای شما محافظت میکنند، اما چیزی بیش از آن انجام میدهند. نقلقولها از تمام فضاهای سفید خروجی فرمان ls محافظت خواهند کرد. راهی وجود ندارد که BASH بتواند تشخیص بدهد کدام بخشهای خروجی فرمان ls نام فایلها را نمایندگی میکنند. خروجی فرمان ls یک رشته ساده است، و BASH با آن به همین عنوان رفتار میکند. بعد
بنابراین چه کار بکنیم؟ به طوری که قبلاً پیشنهاد نمودم، جانشینها بهترین دوست شما هستند:
$for file in * .mp3 >do rm "$ file" >done
حالا، BASH میداند که با نام فایلها سروکار دارد، و نام فایها را میشناسد، و بنابراین به طور مطلوبی آنها راتفکیک میکند. نتیجه بسط جابشین چنین است:
حالا بیایید به حلقه
$ # ماشین نوشیدنی، نوشیدنیها را در ازای بهای ۲۰ سنت تحویل میدهد $while read-p $ \'The sweet machine.\\n Insert 20c and enter your name: \'name >do echo "The machine spits out three lollipops at$ name ." >done
$ # هر پنج دقیقه یکبار ایمیل شما را بررسی میکند $while sleep 300 >do kmail--check >done
$ # برای برخط(آنلاین) شدن مجدد میزبان منتظر میماند $while ! ping-c 1 -W 1 "$ host " >do echo "$ host is still unavailable." >done ; echo-e "$ host is available again.\\a"
حلقه
$ # برای برگشت میزبان به حالت آماده برقراری ارتباط منتظر میماند $until ping-c 1 -W 1 "$ host " >do echo "$ host is still unavailable." >done ; echo-e "$ host is available again.\\a"
در عمل، اکثر مردم حقیقتاً از حلقه
بالإخره، از دستور داخلی continue برای پرش به جلو بدون اجرای بقیه بدنه و اجرای دور بعدی تکرار حلقه، و دستور داخلی break برای پریدن به خارج از حلقه و ادامه دستورات پس از حلقه در اسکریپت، میتوانید استفاده کنید. این دستورات با هر دو حلقه
در مستندات گنو: Looping Constructs
در پرسش و پاسخهای رایج:
چگونه میتوانم یک دستور را با تمام فایلهای دارای پسوند .gz اجرا کنم؟
چگونه میتوانم از اعدادی که با صفر شروع میشوند مثل 01 و 02 در یک حلقه استفاده کنم؟
چطو میتوانم نام فایلهای شامل کاراکتر فاصله یا سطر جدید یا هر دو را پیدا کرده وبا آنها کار کنم؟
میخواهم بررسی کنم که آیایک کلمه در یک لیست وجود دارد( یا یک عنصر عضوی از یک مجموعه هست).
-
حلقه: یک حلقه ساختاری است که برای تکرار کد تا موقع تحقق یک وضعیت معین، طراحی میشود. در آن نقطه حلقه متوقف میشود و کد بعد از آن اجرا میگردد.
for (کلمهکلیدی): یک حلقهfor نوعی حلقه است که یک متغیر را به ترتیب، معادل عناصر لیستی از کمیتها قرار میدهد، و بدنه را با آن متغیر اجرا میکند، و تا تمام شدن لیست تکرار میکند.while (کلمهکلیدی): یک حلقهwhile نوعی حلقه است که اجرای کد را تا موقعی که یک دستور معین(قبل از هر تکرار اجرامیشود) به طور موفق اجرا میشود، ادامه میدهد.until (کلمهکلیدی): یک حلقهuntil نوعی حلقه است که اجرای کد را تا موقعی که یک دستور معین(قبل از هر تکرار اجرامیشود) به طور ناموفق اجرا میشود، ادامه میدهد..