في هذا القسم ، ستتعرف على حلقات for و while و until. لماذا لا يتم تنفيذ for loop في حلقة bash لمخرج الدليل

دورة لتختلف قليلاً عن نظائرها في لغات البرمجة الأخرى. بادئ ذي بدء ، يوفر لك القدرة على تنفيذ إجراءات متسلسلة على "الكلمات" في سلسلة.

دورة في حينينفذ جزءًا من التعليمات البرمجية إذا كان تعبير الاختبار صحيحًا ؛ ويتوقف إذا كان خطأ (أو حدث فاصل حلقة محدد صراحة داخل الكود القابل للتنفيذ).

دورة حتىيكاد يكون متطابقًا مع حلقة while. الاختلاف الوحيد هو أن الكود يتم تنفيذه إذا كان التعبير الذي يتم اختباره خاطئًا.

إذا افترضت أنه بينما وحتى متشابهان جدًا ، فأنت على صواب.

7.1 مثال للحلقة

#! / bin / bash لـ i بـ $ (ls) ؛ هل البند صدى: $ فعلت

في السطر الثاني ، نمثل i كمتغير يتلقى القيم المختلفة الموجودة في $ (ls).

يمكن أن يكون الخط الثالث أطول إذا لزم الأمر ؛ أو يمكن أن يكون هناك عدة أسطر قبل الانتهاء (السطر الرابع).

"تم" (السطر الرابع) يشير إلى أن الكود الذي يستخدم قيمة $ i ينتهي وأن $ i يحصل على قيمة جديدة.

هذا النص ليس له أهمية تذكر. سيكون الاستخدام الأكثر فائدة للحلقة for هو استخدامها لتحديد ملفات معينة فقط في المثال السابق.

7.2 C- مثل ل

اقترح fiesh إضافة نموذج الحلقة هذا. هذه حلقة for ، تشبه إلى حد كبير في C و Perl وما شابه ذلك.

#! / bin / bash for i في `seq 1 10` ؛ هل صدى $ فعلت

7.3 مثال على حلقة while:

#! / bin / bash COUNTER = 0 بينما [$ COUNTER -lt 10]؛ do echo العداد هو $ COUNTER دع COUNTER = COUNTER + 1 تم إنجازه

هذا البرنامج النصي "يحاكي" البنية المعروفة (في C ، Pascal ، perl ، إلخ) "for".

ملخص سريع للاختلاف في أنواع الدورات:

لـ - سينفذ إجراءً طالما أن هناك كائنات يجب تنفيذها (على سبيل المثال ، قراءة دفق من stdin أو ملف أو وظيفة) ؛
بينما - يؤدي العمل حتى حالةصحيح؛
حتى - سيتم تنفيذه حتى حالةلن يصبح صحيحًا ، أي بينما هو خطأ.

لحلقة

ضع في اعتبارك هذا الإصدار من البرنامج النصي الذي يحتوي على حلقة:

$ cat loop.sh #! / bin / bash للمتغير في `ls -1` تم تنفيذ صدى" $ variable "

التركيب اللغوي بسيط للغاية ويظهر بوضوح في المثال:

لمتغير (ابدأ الحلقة) (أعلن عن المتغير المراد تنفيذه) في (أرسل التدفق إلى الحلقة) `ls -1` (الأمر الذي يجب تنفيذه وتمريره إلى المتغير $). ما تم فعله وفعله هما "جسم" الحلقة ، حيث سيتم تنفيذ الإجراءات الرئيسية على البيانات المستلمة ، و echo "متغير $" هو الإجراء الفعلي الذي تقوم به الحلقة.

سنقوم الآن بتغيير المثال قليلاً ، وبدلاً من تحديد الأمر صراحةً ، سنطبق المتغير الثاني:

$ cat loop.sh #! / bin / bash ls = `ls -1` للمتغير في $ ls نفذ صدى" $ variable "

الآن يتم تمرير الأمر ls -1 في متغير منفصل ، مما يسمح بمزيد من المرونة في العمل مع الحلقة. بدلًا من وجود متغير في حلقة ، يمكنك أيضًا استخدام دالة:

$ cat loop.sh #! / bin / bash lsl () (ls -1) للمتغير في `lsl` نفذ صدى" $ variable "

الشرط الرئيسي لحلقة for هو أنه سيتم تنفيذها طالما أن الأمر الذي تم تمريره إليها يحتوي على كائنات للعمل. استنادًا إلى المثال أعلاه - طالما أن هناك ملفات لعرضها في قائمة ls -1 - فإن الحلقة ستمررها إلى متغير وتنفذ "جسم الحلقة". بمجرد انتهاء قائمة الملفات في الدليل ، ستنهي الحلقة تنفيذها.

دعونا نعقد المثال قليلا.

يحتوي الدليل على قائمة بالملفات:

$ ls -1 ملف 1 ملف 2 ملف 3 ملف 4 ملف 5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

نحتاج أن نختار منهم فقط أولئك الذين ليس لديهم كلمة " رقم«:

$ cat loop.sh #! / bin / bash lsl = `ls -1` للمتغير في $ lsl do echo" $ variable "| grep -v "لا" تم $ ./loop.sh file1 file2 file3 file4 file5 loop.sh

في الحلقة ، يمكنك أيضًا استخدام التعبيرات الشرطية ( التعبيرات الشرطية) […] لفحص الشروط وبيان break لمقاطعة الحلقة إذا تم تشغيل الشرط.

ضع في اعتبارك هذا المثال:

$ cat loop.sh #! / bin / bash lsl = `ls -1` للمتغير في $ lsl افعل إذا [$ variable! =" loop.sh "] ثم صدى" $ variable "| grep -v "لا" آخر كسر فاي فعلت

ستستمر الحلقة حتى يتم مواجهة ملف loop.sh. بمجرد وصول تنفيذ الحلقة إلى هذا الملف ، سيتم مقاطعة الحلقة بواسطة الأمر break:

$ ./loop.sh file1 file2 file3 file4 file5

مثال آخر هو استخدام العمليات الحسابية قبل تنفيذ جسم الحلقة مباشرة:

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

هنا قمنا بتعيين ثلاثة أوامر تحكم - العد = 1 ، حالة التحكم - بينما العدد أقل من 11 ، والأمر المراد تنفيذه - العد +1:

حلقات WHILE و UNTIL

مثال بسيط يوضح جيدًا كيفية عمل حلقة while:

$ cat loop.sh #! / bin / bash count = 0 بينما [$ count -lt 10] do ((count ++)) echo $ count تم

قمنا بتعيين المتغير $ count على صفر ، ثم نبدأ حلقة whi le بالشرط "بينما $ count أقل من عشرة ، نفّذ الحلقة." في جسم الحلقة ، ننفذ زيادة postfix+1 للمتغير $ count ثم اطبع النتيجة إلى stdout.

نتيجة التنفيذ:

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

بمجرد أن أصبحت قيمة المتغير بالدولار 10 ، تنتهي الحلقة.

مثال جيد للحلقة "اللانهائية" التي توضح كيفية العمل:

$ cat loop.sh #! / bin / bash count = 10 بينما [1 = 1] do ((count ++)) echo $ count تم $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^ C

تعمل الحلقة حتى بنفس الطريقة ، ولكن "في الاتجاه المعاكس":

$ cat loop.sh #! / bin / bash count = 0 حتى [$ count -gt 10] do ((count ++)) echo $ count تم

هنا نضع شرطًا مشابهًا ، لكن بدلاً من "بينما المتغير أقل من 10" - نشير إلى "حتى يصبح المتغير أكثر من 10". نتيجة التنفيذ:

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

إذا تم تنفيذ المثال أعلاه لـ "حلقة لانهائية" باستخدام حتى - o فلن ينتج أي شيء ، على عكس الوقت:

$ cat loop.sh #! / bin / bash count = 10 حتى [1 = 1] تفعل ((count ++)) echo $ count تم $ ./loop.sh $

لأن " حالة"في البداية" حقا"- لن يتم تنفيذ جسم الحلقة.

كما هو الحال في حلقة for ، يمكن استخدام الوظائف في while و until. على سبيل المثال ، حلقة من برنامج نصي من العالم الحقيقي يتحقق من حالة الخادم هر(يتم أخذ PID في النظام SLES، قد تختلف في الأنظمة الأخرى) ، نسخة مبسطة قليلاً:

$ cat loop.sh #! / bin / bash check_tomcat_status () (RUN = `ps aux | grep tomcat | grep -v grep | grep java | awk" (print $ 2) "`) أثناء check_tomcat_status do if [-n " $ RUN "] ثم اطبع" تحذير: لا يزال Tomcat يعمل مع PID $ RUN. " آخر printf "Tomcat توقف ، متابعة ... nn" break fi done

نتيجة التنفيذ:

تحذير $ ./loop.sh: لا يزال Tomcat يعمل مع PID 14435 26548. تحذير: لا يزال Tomcat يعمل مع PID 14435 26548. تحذير: لا يزال Tomcat يعمل مع PID 14435 26548. تحذير: لا يزال Tomcat يعمل مع PID 14435 26548. تحذير: لا يزال Tomcat يعمل مع PID 14435 26548. يعمل مع PID 14435 26548. تحذير: لا يزال Tomcat يعمل مع PID 14435 26548. تحذير: لا يزال Tomcat يعمل مع PID 14435 26548. تحذير: لا يزال Tomcat يعمل مع PID 14435

النسخة الكاملة:

Check_tomcat_status () (RUN = `ps aux | grep tomcat | grep -v grep | grep java | awk" (print $ 2) "`) while check_tomcat_status؛ افعل إذا [-n "$ RUN"] ثم اطبع "WARNING: Tomcat لا يزال يعمل مع PID $ RUN. هل تريد إيقافه؟" أجب "إيقاف Tomcat ..." "متابعة التثبيت ..." && $ CATALINA_HOME / bin / shutdown. sh 2 &> 1 / dev / null || استراحة النوم 2 إذا [-n "$ RUN"] ثم اطبع "Tomcat ما زال يعمل. اقتله؟" أجب "Killing Tomcat ..." "متابعة التثبيت ... n" && kill $ RUN || استراحة من النوم 2 وإلا اطبع "توقف تومكات ، يستمر ... nn" تم كسر الملف

تم وصف وظيفة الإجابة في المقالة ، ولكن هنا يتم استخدام نسخة محسنة قليلاً:

Answer () (أثناء قراءة الرد ؛ قم بعمل echo case $ response في |) printf "$ 1n" return 0 break ؛؛ |) printf "$ 2n" إرجاع فاصل واحد ؛؛ *) printf "الرجاء إدخال Y (نعم) أو N (لا)!" esac تم)

هنا يمكنك استخدام كل من while and until - ولكن ليس حلقة for ، لأن من الممكن أن تعمل مرة واحدة (حصلت على PID وانتهت).

تدعم قشرة bash حلقات for ، والتي تتيح لك تكرار تسلسل القيم. هذا هو الهيكل الأساسي لهذه الحلقات:

بالنسبة لـ var في القائمة ، يتم تنفيذ الأوامر
في كل تكرار للحلقة ، ستتم كتابة القيمة التالية من القائمة إلى متغير var. لذلك ، في المرور الأول للحلقة ، سيتم استخدام القيمة الأولى من القائمة. في الثانية - الثانية ، وهكذا - حتى تصل الدورة إلى العنصر الأخير.

التكرار على القيم البسيطة

ربما يكون أبسط مثال على حلقة for في نصوص bash هو التكرار على قائمة من القيم البسيطة:

#! / bin / bash لـ var في أول ثاني ثالث رابع خامس do echo تم تنفيذ عنصر $ var
يتم عرض نتائج هذا البرنامج النصي أدناه. من الواضح أن العناصر من القائمة يتم إدخالها بالتسلسل في المتغير $ var. يحدث هذا حتى تصل الدورة إلى آخرها.


حلقة بسيطة

يرجى ملاحظة أن المتغير $ var يحتفظ بقيمته عند الخروج من الحلقة ، ويمكن تغيير محتوياته ، بشكل عام ، يمكنك العمل معه كما هو الحال مع أي متغير آخر.

التكرار على القيم المعقدة

يمكن أن تحتوي القائمة المستخدمة لتهيئة حلقة for ليس فقط على سلاسل بسيطة تتكون من كلمة واحدة ، ولكن أيضًا على عبارات كاملة ، والتي تتضمن عدة كلمات وعلامات ترقيم. على سبيل المثال ، قد يبدو الأمر كله كما يلي:

#! / bin / bash لـ var في "الثانية" "" الثالثة "" I’ll do it "do echo" This is: $ var "done
هذا ما يحدث بعد مرور هذه الحلقة بالقائمة. كما ترى ، النتيجة متوقعة تمامًا.


التكرار على القيم المعقدة
TNW-CUS-FMP - رمز ترويجي لخصم 10٪ على خدماتنا ، متاح للتفعيل في غضون 7 أيام "

تهيئة الحلقة بقائمة تم الحصول عليها من نتائج الأمر

هناك طريقة أخرى لتهيئة حلقة for وهي تمرير قائمة ، والتي تكون نتيجة أمر ما. هذا هو المكان الذي يتم فيه استخدام استبدال الأوامر لتنفيذها والحصول على نتائج عملهم.

#! / bin / bash file = تم تنفيذ "myfile" لـ var في $ (cat $ file)
يستخدم هذا المثال الأمر cat لقراءة محتويات الملف. يتم تمرير قائمة القيم الناتجة إلى الحلقة وعرضها. يرجى ملاحظة أن الملف الذي نشير إليه يحتوي على قائمة بالكلمات مفصولة بأحرف تغذية الأسطر ، ولا يتم استخدام مسافات.


التكرار الحلقي من خلال محتويات الملف

يجب ألا يغيب عن الأذهان أن مثل هذا النهج ، إذا كان من المتوقع معالجة البيانات سطرًا بسطر ، لن يعمل مع ملف بهيكل أكثر تعقيدًا ، قد تحتوي سطوره على عدة كلمات مفصولة بمسافات. ستعالج الحلقة الكلمات الفردية وليس الخطوط.

ماذا لو لم يكن هذا ما تريده على الإطلاق؟

فواصل المجال

يكمن سبب الخصوصية المذكورة أعلاه في متغير بيئة خاص يسمى IFS (فاصل المجال الداخلي) الذي يسمح لك بتحديد فواصل المجال. بشكل افتراضي ، يعامل bash الأحرف التالية كمحددات للحقول:
  • الفراغ
  • حرف جدولة
  • حرف تغذية السطر
إذا واجهت bash أيًا من هذه الأحرف في البيانات ، فإنها تفترض أن القيمة المستقلة التالية في القائمة موجودة أمامها.

لحل المشكلة ، يمكنك تغيير متغير بيئة IFS مؤقتًا. إليك كيفية القيام بذلك في برنامج نصي باش ، بافتراض أنك تحتاج فقط إلى سطر جديد كفاصل حقل:

IFS = $ "\ n"
بعد إضافة هذا الأمر إلى نص برمجي bash ، سيعمل كما هو متوقع ، متجاهلاً المسافات وعلامات التبويب ، ومعالجة تغذية الأسطر فقط كمحددات حقل.

#! / bin / bash file = "/ etc / passwd" IFS = $ "\ n" لـ var في $ (cat $ file) نفذ صدى "$ var"
إذا قمت بتشغيل هذا البرنامج النصي ، فسيخرج بالضبط ما هو مطلوب منه ، مما يمنح ، في كل تكرار للحلقة ، الوصول إلى السطر التالي المكتوب في الملف.


الزحف إلى ملف سطرًا بسطر في حلقة for

يمكن استخدام الشخصيات الأخرى كمحددات. على سبيل المثال ، عرضنا أعلاه محتويات ملف / etc / passwd. يتم فصل بيانات المستخدم في السلاسل بنقطتين. إذا كنت بحاجة إلى معالجة مثل هذه الأسطر في حلقة ، فيمكن تكوين IFS على النحو التالي:

تجاوز الملفات الموجودة في الدليل

أحد الاستخدامات الأكثر شيوعًا لحلقات for في نصوص bash هو اجتياز الملفات في دليل ومعالجة تلك الملفات.

على سبيل المثال ، إليك كيفية سرد الملفات والمجلدات:

#! / bin / bash للملف في / home / likegeeks / * افعل إذا [-d "$ file"] ثم صدى "$ file is a directory" elif [-f "$ file"] ثم echo "$ file is a ملف "fi done
إذا كنت قد اكتشفت من هذه السلسلة من المقالات ، فيجب أن تفهم بنية بناء if-then ، وكذلك كيفية التمييز بين الملف والمجلد. إذا وجدت صعوبة في فهم الكود أعلاه ، فيرجى إعادة قراءة هذه المادة.

هذا ما سيخرجه البرنامج النصي.


إخراج محتويات مجلد

لاحظ كيف نقوم بتهيئة الحلقة ، أي حرف البدل "*" في نهاية عنوان المجلد. يمكن اعتبار هذا الرمز كنمط ، بمعنى: "جميع الملفات بأي أسماء". يسمح لك بتنظيم الاستبدال التلقائي لأسماء الملفات التي تتطابق مع النمط.

عندما نختبر شرطًا في عبارة if ، فإننا نضع اسم المتغير بين علامات اقتباس. يتم ذلك لأن اسم الملف أو المجلد قد يحتوي على مسافات.

C- ستايل للحلقات

إذا كنت معتادًا على لغة برمجة C ، فقد يبدو بناء الجملة لوصف bash for loops غريبًا بالنسبة لك ، حيث من الواضح أنك معتاد على مثل هذا الوصف للحلقات:

لـ (أنا = 0 ؛ أنا< 10; i++) { printf("number is %d\n", i); }
في نصوص bash ، يمكنك استخدام حلقات for ، التي يبدو وصفها مشابهًا جدًا لحلقات النمط C ، على الرغم من وجود بعض الاختلافات هنا. يبدو مخطط الحلقة باستخدام نهج مشابه كما يلي:

لـ ((القيمة الأولية المتغيرة ؛ حالة نهاية الحلقة ؛ التغيير المتغير))
في bash ، يمكن كتابتها على النحو التالي:

لـ ((أ = 1 ؛ أ< 10; a++))
وإليك مثال عملي:

#! / bin / bash لـ ((i = 1 ؛ i<= 10; i++)) do echo "number is $i" done
سيقوم هذا الرمز بطباعة قائمة أرقام من 1 إلى 10.

حلقات نمط C

حائط اللوب

ليست جملة for هي الطريقة الوحيدة لتنظيم الحلقات في نصوص bash. يمكنك أيضًا استخدام حلقات while هنا. في مثل هذه الحلقة ، يمكنك تعيين أمر للتحقق من حالة معينة وتنفيذ جسم الحلقة حتى تعيد الحالة المحددة صفرًا ، أو إشارة إلى إكمال عملية معينة بنجاح. عندما يُرجع شرط الحلقة قيمة غير صفرية ، مما يعني وجود خطأ ، ستتوقف الحلقة.

فيما يلي رسم تخطيطي لكيفية تنظيم حلقات while.
أثناء أمر فحص الحالة
فعل
فرق أخرى
فعله

لنلقِ نظرة على مثال نص برمجي به مثل هذه الحلقة:

#! / bin / bash var1 = 5 بينما تم تنفيذ [$ var1 -gt 0] echo $ var1 var1 = $ [$ var1 - 1]
عند مدخل الحلقة ، يتم التحقق مما إذا كان المتغير var1 $ أكبر من الصفر. إذا كان الأمر كذلك ، يتم تنفيذ جسم الحلقة ، حيث يتم طرح واحد من قيمة المتغير. يحدث هذا في كل تكرار ، بينما نقوم بطباعة قيمة المتغير على وحدة التحكم قبل تعديلها. بمجرد أن يكون $ var1 هو 0 ، تنتهي الحلقة.

نتيجة حلقة while

إذا لم تقم بتعديل المتغير $ var1 ، فسيؤدي ذلك إلى وقوع النص في حلقة لا نهائية.

حلقات متداخلة

يمكن استخدام أي أوامر في جسم الحلقة ، بما في ذلك تشغيل حلقات أخرى. تسمى هذه البنى الحلقات المتداخلة:

#! / bin / bash لـ ((أ = 1 ؛ أ<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
فيما يلي ما سيخرجه هذا البرنامج النصي. كما ترى ، أولاً ، يتم تنفيذ التكرار الأول للحلقة الخارجية ، ثم ثلاث تكرارات للحلقة الداخلية ، بعد اكتمالها ، يتم تشغيل الحلقة الخارجية مرة أخرى ، ثم الحلقة الداخلية مرة أخرى.

حلقات متداخلة

معالجة محتوى الملف

الاستخدام الأكثر شيوعًا للحلقات المتداخلة هو معالجة الملفات. لذا ، فإن الحلقة الخارجية مشغولة بالتكرار فوق أسطر الملف ، بينما تعمل الحلقة الداخلية بالفعل مع كل سطر. على سبيل المثال ، هذه هي الطريقة التي تبدو بها معالجة ملف / etc / passwd:

#! / bin / bash IFS = $ "\ n" للإدخال في $ (cat / etc / passwd) تفعل الصدى "القيم في $ entry -" IFS =: للقيمة في $ entry ، نفذ صدى "$ value" فعله
هناك نوعان من الحلقات في هذا البرنامج النصي. يتم تنفيذ الحلقة الأولى عبر الأسطر ، باستخدام حرف تغذية السطر كفاصل. الجزء الداخلي هو تحليل سلاسل مشغول ، يتم فصل حقولها بنقطتين.

معالجة بيانات الملف

يمكن استخدام هذا الأسلوب عند معالجة ملفات CSV ، أو أي ملفات مماثلة ، عن طريق كتابة حرف محدد إلى متغير بيئة IFS حسب الحاجة.

التحكم في الدورة

ربما ، بعد دخول الحلقة ، سيكون من الضروري إيقافها عندما يصل متغير الحلقة إلى قيمة معينة ، والتي لا تتوافق مع الشرط المحدد في البداية لنهاية الحلقة. هل سيكون من الضروري في مثل هذه الحالة انتظار الإكمال الطبيعي للدورة؟ بالطبع لا ، وفي مثل هذه الحالات يكون الأمران التاليان مفيدًا:
  • فترة راحة
  • استمر

أمر كسر

يسمح لك هذا الأمر بمقاطعة تنفيذ الحلقة. يمكن استخدامه لكل من حلقات for و while loops:

#! / bin / bash لـ var1 في 1 2 3 4 5 6 7 8 9 10 افعل إذا تم تنفيذ [$ var1 -eq 5] ثم كسر fi echo "Number: $ var1"
مثل هذه الحلقة ، في ظل الظروف العادية ، سوف تمر عبر قائمة القيم الكاملة من القائمة. ومع ذلك ، في حالتنا ، سيتم قطع تنفيذها عندما يكون المتغير $ var1 يساوي 5.

ترك حلقة for مبكرًا

إليك نفس الشيء في حلقة while:

#! / bin / bash var1 = 1 أثناء تنفيذ [$ var1 -lt 10] إذا تم تنفيذ [$ var1 -eq 5] ثم كسر fi echo "التكرار: $ var1" var1 = $ (($ var1 + 1))
يتم تنفيذ تعليمة break عندما تكون قيمة $ var1 تساوي 5 يكسر الحلقة. ستخرج وحدة التحكم كما في المثال السابق.

متابعة الأمر

عند مواجهة هذا الأمر في جسم الحلقة ، ينتهي التكرار الحالي مبكرًا ويبدأ التكرار التالي ، ولا تخرج الحلقة. دعنا نلقي نظرة على أمر المتابعة في الحلقة for:

#! / bin / bash لـ ((var1 = 1 ؛ var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
عندما يتم استيفاء الشرط داخل الحلقة ، أي عندما يكون $ var1 أكبر من 5 وأقل من 10 ، ستنفذ shell أمر المتابعة. يؤدي هذا إلى تخطي الأوامر المتبقية في جسم الحلقة والمتابعة إلى التكرار التالي.

يستمر الأمر في حلقة for

إخراج المعالجة المنفذة في حلقة

يمكن معالجة إخراج البيانات من الحلقة إما عن طريق إعادة توجيه الإخراج أو الأنابيب. يتم ذلك عن طريق إضافة أوامر معالجة الإخراج بعد العبارة المنجزة.

على سبيل المثال ، بدلاً من عرض ما يتم عرضه في حلقة على الشاشة ، يمكنك كتابته بالكامل في ملف أو نقله إلى مكان آخر:

#! / bin / bash لـ ((أ = 1 ؛ أ< 10; a++)) do echo "Number is $a" done >صدى myfile.txt "انتهى".
سيقوم برنامج التضمين بإنشاء الملف myfile.txt وإعادة توجيه إخراج من أجل هذا الملف. دعنا نفتح الملف ونتأكد من أنه يحتوي على ما هو متوقع بالضبط.

إعادة توجيه إخراج الحلقة إلى ملف

مثال: البحث عن الملفات القابلة للتنفيذ

دعنا نستخدم ما غطيناه حتى الآن ونكتب شيئًا مفيدًا. على سبيل المثال ، إذا كنت بحاجة إلى معرفة الملفات القابلة للتنفيذ المتوفرة على النظام ، فيمكنك فحص جميع المجلدات المكتوبة إلى متغير البيئة PATH. لدينا بالفعل ترسانة كاملة من الأدوات التي نحتاجها لهذا ، نحتاج فقط إلى تجميعها معًا:

#! / bin / bash IFS =: للمجلد في $ PATH ، قم بعمل echo "$ folder:" للملف الموجود في $ folder / * do if [-x $ file] ثم صدى "$ file" حتى تم إنجازه
مثل هذا البرنامج النصي ، الصغير وغير المعقد ، جعل من الممكن الحصول على قائمة بالملفات القابلة للتنفيذ المخزنة في مجلدات من PATH.

ابحث عن الملفات القابلة للتنفيذ في مجلدات من متغير PATH

النتائج

تحدثنا اليوم عن حلقات for and while في نصوص bash ، وكيفية تشغيلها ، وكيفية إدارتها. يمكنك الآن معالجة السلاسل باستخدام محددات مختلفة في الحلقات ، وتعرف كيفية إعادة توجيه إخراج البيانات في حلقات إلى الملفات ، وكيفية عرض محتويات الدلائل وتحليلها.

بافتراض أنك مطور نصوص bash لا يعرف إلا ما هو موصوف في هذه السلسلة من المقالات ، وفي هذه الثانية ، يمكنك بالفعل كتابة شيء مفيد. إلى الأمام هو الجزء الثالث ، بعد فهم أي منها ، ستتعلم كيفية تمرير المعلمات ومفاتيح تبديل سطر الأوامر إلى نصوص bash ، وماذا تفعل بكل هذا.

في هذه المحاضرة ، نواصل التعرف على سحق... أود أن أذكركم بأننا ندرس هذه العناصر سحقلمساعدتنا على فهم البرامج النصية لنظام التشغيل. الحلقات والوظائف هي بالتأكيد عناصر من هذا القبيل. إذا درس شخص ما البرمجة ، فلن تكون هناك صعوبات في فهم هذه القضايا.

لحلقة

دورة لالخامس سحقنوعان. لنفكر أولاً في الإصدار الكلاسيكي ل... النظرة العامة على النحو التالي:

بين العناصر لو فييتم تعيين متغير ، والذي بدوره يأخذ قيمة من سلسلة من القيم المحددة بين فيو فعل... ما بين فعلو فعلههناك أوامر يتم تنفيذها في كل مرة يغير فيها متغير قيمته. تتوقف الحلقة عن العمل عندما يأخذ المتغير آخر قيمة من التسلسل. القيم في التسلسل مفصولة بمسافة.

وإليك مثال عملي:

يمكن تحديد تسلسل القيم بطرق مختلفة. صراحة - كما في المثال أعلاه ، أو باستخدام متغيرات أخرى ، أو باستخدام أوامر خاصة. لنلق نظرة على بعض الأمثلة. نظرًا لأنه يتم تعيين القيم مفصولة بمسافات ، يمكن أن تكون هذه القيم أي متغير يحتوي على سلسلة بها مسافات:

ستكون النتيجة هي نفسها كما في المثال الأول.

إذا كنت بحاجة إلى تحديد تسلسل من الأرقام ، يمكنك استخدام الأمر فيما يليهاوآلية الاستبدال. فريق فيما يليهاإرجاع تسلسل من القيم الرقمية إلى الشاشة. بناء الجملة بسيط وسيتضح من المثال أدناه:

نتيجة:

دعنا نعود إلى النوع الثاني ل... غالبًا ما تجد في البرامج النصية ما يسمى بالمتغير المشابه للغة C لوالذي يستخدم للحلقات المستندة إلى الأرقام. دعنا نفكر في مثال على الفور:

يتم تنفيذ الحلقة طالما أن الشرط الذي يتم التحقق منه في التعبير صحيح. بمجرد أن يعود التعبير خطأ ، يتم إنهاء تنفيذ الحلقة.

مثال عملي:

#! / بن / باش
أنا = 1
بينما [$ i -lt 7]
فعل
صدى $ ط
دعني = أنا + 1
فعله

في مثالنا ، تم التحقق من أن المتغير أناأقل (-lt) ، رقم 7 وإذا كان الأمر كذلك ، فسيتم عرض قيمة المتغير. تعبير دعني = أنا + 1، يزيد المتغير بمقدار واحد ، ويتحقق مرة أخرى ، وهكذا. دعنا يخبر المترجم أن يتعامل مع الحجج كقيم عددية. يمكن كتابة هذا السطر باسم اسمحوا لي ++(ج مثل الخيار). بزيادة الرقم بأكثر من واحد يمكنك كتابته على النحو التالي: دعني + = 2- في هذه الحالة أناستزيد بزيادات قدرها 2. خيار آخر لزيادة المتغير هو استخدام الآلة الحاسبة المضمنة (تعمل فقط مع الأعداد الصحيحة). يمكن الوصول إلى الآلة الحاسبة من خلال قوسين مزدوجين: أنا = دولار (($ i + 1))أو من خلال المربعات: أنا = $ [$ i + 1]يمكنك أيضًا استخدام الآلة الحاسبة في سطر الأوامر:

مع الحلقات ، يجب أن تكون حريصًا على عدم الحصول على خيار الحلقة اللانهائية. بالمناسبة للتصحيح سحقالبرامج النصية ، يمكنك تغيير السطر الأول إلى #! / bin / bash -xأو قم بتشغيل البرنامج النصي باستخدام الأمر باش -x:

[بريد إلكتروني محمي]: ~ / linux $ bash -x ./testfor.sh
+ أنا = 1
+ "[" 1 -gt 5 "]"
+ صدى أنا = 1
أنا = 1
+ دعني = أنا + 1
+ "[" 2 -gt 5 "]"
+ صدى أنا = 2
أنا = 2
+ دعني = أنا + 1
+ "[" 3 -gt 5 "]"
+ صدى أنا = 3
أنا = 3
+ دعني = أنا + 1
+ "[" 4 -gt 5 "]"
+ صدى أنا = 4
أنا = 4
+ دعني = أنا + 1
+ "[" 5 -gt 5 "]"
+ صدى أنا = 5
أنا = 5
+ دعني = أنا + 1
+ "[" 6 -gt 5 "]"

تأكد من التدرب على كتابة نصوص صغيرة لتعزيز فهمك لكيفية عمل الحلقات سحق.

الوظائف في bash

يتم تطبيق الوظائف في سحقواسع جدا. يتم وصف الوظائف بطريقتين: باستخدام كلمة رئيسية وظيفةوبدونها.

الطريقة الأولى:

وظيفة function_name
{
وظيفة الجسم
}

الطريقة الثانية:

اسم وظيفة ()
{
وظيفة الجسم
}

يتم استدعاء الوظيفة بالاسم في أي مكان في البرنامج النصي ، ولكن فقط بعد وصف الوظيفة نفسها. يمكنك أيضًا تمرير المعلمات إلى الوظائف ، والتي يتم تحديدها بمسافة بعد استدعاء (اسم) الوظيفة. لنفكر في مثال على البرنامج النصي سحق:

#! / بن / باش
وظيفة التمهيدي
{
إذا [$ # -ne 0]
ومن بعد
محلي أ = 1
صدى "عدد المعلمات التي تم تمريرها - $ #"
لأني في [بريد إلكتروني محمي]
فعل
صدى "المعلمة $ a-th هي $ i"
دع ++
فعله
العودة 0
آخر
صدى "لم يتم تمرير أي معلمات"
العودة 1
فاي
}
صدى "استدعاء الوظيفة مع المعلمات:"
التمهيدي أ ب ج
صدى $؟
صدى "استدعاء الوظيفة بدون معلمات:"
التمهيدي
صدى $؟

في هذا المثال ، وظيفة تسمى التمهيدي... استدعاء الوظيفة مع المعلمات: التمهيدي أ ب جوبدون معلمات: التمهيدي... في جسم الوظيفة ، يجب أن تكون جميع التركيبات مألوفة لك ، باستثناء $# , أنا $و [بريد إلكتروني محمي] .$# - إرجاع عدد المعلمات التي تم تمريرها إلى الوظيفة. في مثالنا ، سيكون هذا هو الرقم 3 .[بريد إلكتروني محمي] ترجع جميع المعلمات في سطر واحد. في المثال سيكون أ ب ج... و بعد $1 , $2 , $3 إلخ. يمكنك معالجة كل معلمة بشكل شخصي. $? - يحتوي على الكود الخاص بتنفيذ الأمر الأخير. في مثالنا ، الكود الخاص بتنفيذ الوظيفة.

يمكن أن ترجع الوظيفة أيضًا قيمة عددية عبر كلمة أساسية إرجاع... كقاعدة عامة ، يتم إرجاع القيمة 0 إذا تم تنفيذ الوظيفة بدون أخطاء ، أو إرجاع قيمة غير صفرية إذا حدث خطأ ما. في المثال ، إذا تم استدعاء دالة مع معلمات ، يتم إرجاع القيمة 0 ، وإذا تم استدعاء الوظيفة بدون معلمات ، فسيتم إرجاع الكود 1.

كل شيء يتعلق بتمرير المعلمات إلى وظيفة يعمل بنفس الطريقة مع النص. يمكن للبرنامج النصي أيضًا تمرير المعلمات بنفس الطريقة والتعامل معها بنفس الطريقة باستخدام $#, [بريد إلكتروني محمي]، $ N... من نفس الفئة والخيار - $0 - التي تُرجع اسم الأمر الذي أطلق البرنامج النصي. إذا تم تشغيل البرنامج النصي بواسطة الأمر ./script.shثم صدى $0 سيعود القيمة ./script.sh، وإذا أمر /home/igor/linux/script.shثم سيتم إرجاع القيمة /home/igor/linux/script.sh.