البحث في الموقع
المحتوى عن 'zsh'.
-
يهدِف هذا الدّليل إلى شرح طريقة كتابة سكربتات Shell لتحقيق أغراض مختلفة. يُمكن أن تُستخدم سكربتات Shell لتنفيذ أوامر عديدة، أمر واحد بمعطَيات Arguments كثيرة معقَّدة، أو واجهات أكثر سهولةً في الاستخدام لتوزيع عملك. في الأساس، تُستخدَم سكربتات Shell لتسهيل بعض الأعمال بتشغيلها آليًّا دون اللّجوء لإعادة كتابتها في كلّ مرة تحتاجها. أساسيّات كتابة سكربتات Shell1- تهيئة مجلّد العملمن الجيّد، قبل البدء في كتابة سكربتات Shell، إعدادُ مجلّد لوضعها فيه. يُنصَح بوضع السكربتات الشّخصيّة في مجلّد يوجد على المسار bin/~. ننشئ هذا المجلّد عبر الأمر التّالي: mkdir ~/binنُضيف مسار المجلّد إلى المتغيّر PATH وذلك بتعديل ملفّ etc/profile/ على النّحو التّالي: sudo nano /etc/profileونُضيف الأسطُر التّالية إلى الملفّ: PATH=$PATH:$HOME/bin export PATHاستخدم زرّي CTRL وO لحفظ التّعديلات، وCTRL+X للخروج من محرّر النّصوص nano. ثمّ نعتمد التّغييرات عبر تنفيذ الأمر: source /etc/profileبعض توزيعات لينكس لا تدعم أمر source، في هذه الحالة ينبغي إعادة تشغيل النّظام لاعتماد التّعديلات: sudo rebootملحوظة: للتّأكّد من اعتماد التّغييرات استخدِم الأمر التّالي: printenv PATHوتأكّد من وجود مسار مجلّد السكربتات ضمن المسارات العروضة (يُفصَل بين المسارات بنقطتيْن عموديّتيْن هكذا :). 2- إنشاء ملفّينبغي إنشاء ملفّ تنفيذيّ Executable file حتى يُمكن تشغيل السكربت. الأمران التّاليّان يؤدّيان هذه المهمّة؛ الأوّل ينشِئ ملفًّا والثّاني يجعله قابلًا للتّنفيذ: touch ~/bin/firstscript chmod +x ~/bin/firstscriptنفتح الملفّ بمحرّر نصوص nano للبدْء في إضافة الأوامر إلى السكربت: nano ~/bin/firstscriptتجب إضافة السّطر التّالي في بداية الملفّ حتّى يعرف النّظام أنّه سكربت Shell وبالتّالي ينفّذ الأوامر الموجودةَ فيه بالطّريقة الصّحيحة: #!/bin/shأصبح الملفّ الآن جاهِزًا ليستقبل أي أمر من أوامر لينكس، مثلًا: clear echo "Hello World!"نحفظ الملفّ (CTRL+O) ثمّ نخرج من محرّر النّصوص (CTRL+X). تكفي الآن كتابة اسم السكربت ثم الضّغط على Enter لتنفيذه: firstscriptلا يهمّ من أيّ المسارات نفّذت السكربت، مادام مجلّد العمل موجودًا ضمن متغيّر البيئة PATH. ينبغي أن تحصُل على النّتيجة التّاليّة: 3- مثال لسكربتيُعدّ التّشغيل الآليّ للأعمال المتكرّرة أحد أكثر المجالات الّتي تُستخدَم فيها سكربتات Shell. على سبيل المثال؛ إذا كنت دائمًا تنقل الكثير من الملفّات إلى مجلّد نسخ احتيّاطي Backup، وليكن backup/~، فإنّ بإمكانك إعداد سكربت ينقل أي ملفّ تحدّده إلى المجلّد المطلوب. بهذه الطّريقة يمكن أن تكتُب: filebackup file-name1 file-name2 ...فلنلقِ نظرة على ما نحتاج لمعرفته، قبل البدْء في كتابة السكربتات. أوّل ملحوظة هي أنّ سكربتات Shell لا تستخدم التّرميز الصّلب Hard coding. يعني هذا، في إطار مثالنا، أنّه يمكنك بسهولة تغيير مجلّد النّسخ الاحتيّاطي إذا أردت. كلّ ما عليك فعله هو تعديل أحد الأسطُر الأولى في ملفّ السكربت؛ حيثُ سيظهر المتغيّر الّذي سيخزّن مسار المجلّد مرةً واحدة فقط. لن تحتاج لتعديل ملفّ السكربت لتجربة التّعامل مع المتغيّرات، يمكن ذلك مباشرةً في سطر الأوامر عن طريق كتابة ما يلي: testvariable=teststringأعطينا القيمة teststring للمتغيّر testvariable. يطبع أمر echo محتوى المتغيّر (لاحِظ استخدام $ أمام اسم المتغيّر): echo $testvariableستظهر في سطر الأوامر قيمة المتغيّر testvariable أيّ teststring. يمكننا الآن بعد هذا الاختبار البسيط لعمل المتغيّرات البدءُ في كتابة السّكربت؛ الخطوات هي نفسُها الّتي تحّثنا عنها أعلاه: إنشاء الملفّ، جعله قابلًا للتّنفيذ، ثمّ البدْء في تحريره: touch ~/bin/filebackup chmod +x ~/bin/filebackup nano ~/bin/filebackupينبغي الانتباه إلى أنّ أي سطر يبدأ بعلامة # تعليق، أي أنّه لن يؤثّر على عمل السكربت إلا إذا أُتبعت # بعلامة تعجّب ! في السّطر الأوّل من برنامجك؛ في هذه الحالة يُطلق عليها اسم shebang والّتي شرحنا سابقًا أنّ نظام التّشغيل يعرف عن طريقها أنّ هذا الملفّ سكربت Shell ويُنفّذ الأوامر الموجودة فيه. يأخذ السكربت الشّكلَ التّالي: #!/bin/sh #Backup script #Description: makes a copy of any given file at the backup folder #Author: Your Name #Date: 8/10/2013 #Backup folder; set this variable to any folder you have write permissions on BACKUPFOLDER=~/backup #The script will make sure the folder exists mkdir -p $BACKUPFOLDER #Now the script will copy the given file to the folder cp -a $@ $BACKUPFOLDERنشرح، بعد حفظ الملفّ (CTRL+O) والخروج من محرّر النّصوص (CTRL+X)، عمل السكربت. الأسطُر الأولى كلّها تعليقات؛ عرّفنا بعدها متغيّرًا باسم BACKUPFOLDER نضع فيه مسار المجلّد حيث نُريد نسخ الملفّات. ننفّذ بعدها الأمر mkdir -p $BACKUPFOLDER الّذي يُنشئ مجلّدًا في المسار الموجود في المتغيّر BACKUPFOLDER، إذا كان المجلّد موجودًا مسبقًا لن تظهر أي رسالة خطأ نظرًا لاستخدام خيّار p-. تدلّ علامة @$ في الأمر التّالي، cp، على المعطيات الّتي يمرّرها المستخدِم أثناء تنفيذ السّكربت. لتمرير المعطيات للسكربت فإنّ المستخدِم يكتبها مباشرةً بعد اسم السكربت. يوجد مجلّد الحفظ (وِجهة النّسخ، في هذه الحالة قيمة المتغيّر BACKUPFOLDER) مباشرةً بعد المعطيات الّتي يمرّرها المستخدِم. لتجربة السكربت نفّذ ما يلي، على اعتبار أنّ file1 وfile ملفّان يوجدان في المجلّد حيثُ تنفّذ السكربت: filebackup file1 fileيمكنك إضافة ملفّات بالعدد الّذي تريد، بكتابة أسمائها بعد اسم السكربت، وستُنقَل جميعها إلى مجلّد النّسخ الاحتيّاطيّ. أوامر أساسيّة في Shellتوجد بعض الأوامر الأساسيّة لعرض المعلومات للمستخدِم، ولأخذها منه أيضًا. 1- أمر echoيُستخدَم أمر echo لعرض معلومات للمستخدِم، سواءٌ كانت هذه المعلومات نصًّا أو متغيّرات أو خليطًا من الاثنين. يُمكن استخدام الخيّاريْن n- وe- مع أمر echo؛ يمنع خيّار n- طباعة سطر جديد بعد النّصّ المعروض، أما خيّار e- فيُفعّل استخدام مجموعة الرموز التّالية داخل النّصّ: a\: صوت تحذير - Alert soundb\: فراغ للخلف Backspacec\: لا تطبع سطرًا جديدًاe\: مِحرف الخلوص Escape charactern\: سطر جديدr\: رجوع إلى السّطرt\: جدولة أفقيّة0xx\: محرف ASCII\\: خط مائل عكسي Backslash.على سبيل المثال، يؤدّي الأمران التّاليّان نفس الشّيئ بالضّبط (لاحِظ وجود النّص بين علامتيْ اقتباس): echo -e “Text\c” echo -n “Text”لعرض قيمة متغيّر عن طريق أمر echo أضف اسم المتغيّر مسبوقًا بعلامة $: string=World! echo "Hello $string"يُمكنك خلط نص، أوامر ومتغيّرات في سلسلة محارف String واحدة. يمكنك أيضًا كتابة أمر من سطر واحد يعرض نصًّا من أسطر عديدة؛ كلّ ما عليك فعله هو كتابة n\ في المكان الّذي تُريد بدْءَ سطرٍ جديد منه. 2- تهيئة النّصوص باستخدام أمر echoيُمكن لأمر echo عرض النّصوص وتهيئتها بألوان وأساليب متنوّعة؛ ولكنّ نتائج هذه التّهيئة قد لا تكون دومًا متشابهة في الطّرفيّات الموجودة. يجب الانتباه إلى أنّ بعض المستخدمين قد لا يرون نتيجة تهيئة النّصوص بنفس الطّريقة الّتي تظهر لديك. لا يُشكّل هذا الأمر، بما أنّ التّغيير ظاهريّ أساسًا، مشكلًا كبيرًا في غالب الأوقات. يُعرَّف كلُّ تخصيص (جعل الخطّ عريضًا Bold، وضع خطّ تحت النّص، أو تلوينه) بمتتاليّة من محارف الخلوص Escape characters، وهي مجموعة من الرّموز تتبع المِحرف `e\’، على النّحو التّالي: echo -e "This is \e[1mBold"ينتُج عن الأمر السّابق كتابة الجملة This is Bold مع تمييز كلمة Bold بخط عريض. يوضّح الجدول التّالي بعض الرّموز شائعة الاستخدام: خطّ عريضخطّ عاديّخطّ تحت النّصّعكس الألوانe[1m\e[2m\e[4m\e[7m\ يُمكن استخدام هذه الرّموز معًا للحصول على نصّ عريض ومخطوط تحته، ثمّ إعادة تعيين التّأثيرات باستخدام الرّمز e[0m\: echo -e "\e[4mThis \e[1mis\e[0m \e[7man example \e[0mstring"جرّب الأمر وشاهد عمل الرّموز. يعمل تلوين النّصوص بنفس الطّريقة حيثُ يوجد رمز لكلّ لون. تُدرج رموز الألوان مثل ما تُدرج رموز تهيئة النّص المذكورة في الفقرة السّابقة. يوضّح الجدول التّالي رموز الألوان الأكثر شيوعًا. يوجد رمز للون النّص وآخر لخلفيّته. أسودe[30m\e[40m\أحمرe[31m\e[41m\أخضرe[32m\e[42m\أصفرe[33m\e[43m\أزرقe[34m\e[44m\أرجوانيّe[35m\e[45m\سماويّe[36m\e[46m\رمادي فاتحe[37m\e[47m\اللّون الافتراضيّe[39m\e[49m\إن أردنا مثلًا نصًّا بلون أحمر فالرّمز هوe[31m\، أمّا إذا أردنا خلفيّة بلون أحمر فالرّمز هو e[41m\. يُمكنك استخدام ألوان مختلفة لكلّ من النّص والخلفيّة، كما أنّ بإمكانك استخدام رموز تهيئة النّصّ المذكورة في الفقرة السّابقة إلى جانب رموز ألوان النّصّ والخلفيّة. 3- أمر readيُستدعى أمر read لأخذ بيانات من المستخدِم. يسجّل أمر read كلّ ما يكتبه المستخدِم ابتداءً من استدعاء الأمر إلى أن يضغط على زرّ ENTER، يسجّله في متغيّر. يوجد معطًى واحد للاستخدام مع أمر read وهو اسم المتغيّر الّذي سيُحتفظ فيه بما يكتبه المستخدِم. في ما يلي مثال لسكربت مختصَر يُنشئ مجلّدًا بالاسم الّذي يختاره المستخدِم: #!/bin/bash read foldername mkdir foldernameيُمكن ملاحظة أنّ السكربت السّابق لا يمتلك أيّ واجهة للتّفاعل مع المستخدم. كيف يُمكن للمستخدِم أن يعرف مالّذي عليه كتابته؟ 4- مثال على سكربتسنطبّق، عبر المثال التّالي، كلّ ما تعلّمناه حتى الآن. سنعرِض رسائل مخصَّصة ومنسَّقة للمستخدِم، ثمّ نأخذ منه البيانات الّتي نحتاجها. عرضنا في بداية هذا الشّرح مثالًا لسكربت ينسخ احتيّاطيًّا مجموعة من الملفّات؛ سنعيد كتابة هذا السّكربت لنطلُب من المستخدِم مالملفّات الّتي يُريد نسخَها. نعدّ بدايةً الملفّ ونفتحه للتّحرير: touch ~/bin/filebackup2 chmod +x ~/bin/filebackup2 nano ~/bin/filebackup2ونُعيد كتابته بحيث تكون لديه واجهة مع المستخدِم: #!/bin/bash #Backup script 2.0 #Description: makes a copy of any given file at the backup folder #Author: Your Name #Date: 5/27/2015 #Request the backup folder from the user: echo -e "\e[1m\e[32mFile Backup Utility\n\e[39m\e[0mPlease input your backup folder:" read BACKUPFOLDER #The script will make sure the folder exists mkdir -p $BACKUPFOLDER #Request files to be backed up: echo -e "\e[47m\e[30mWhich files do you want backed up?\e[39m\e[49m" read FILES cp -a $FILES $BACKUPFOLDERيُظهر السكربت رسالة للمستخدِم، بطريقة منسَّقة، تدعوه أوّلًا لإدخال اسم المجلّد الّذي ستُحفَظ فيه النّسخ الاحتيّاطيّة ويحتفظ باسم المجلّد في المتغيّر BACKUPFOLDER، ثمّ يُنشئ السكربت المجلّد إن لم يكن موجودًا. الخطوة التّاليّة هيّ إظهار رسالة تطلُب من المستخدم إدراج أسماء الملفّات المُراد نسخُها ويحفظها في متغيّر باسم FILES. الخطوة الأخيرة هي نسخ الملفّات إلى المجلّد عبر الأمر cp. غطّينا في الفقرات السّابقة الأوامر الأساسيّة الّتي تُمكِّن من كتابة سكربتات تتفاعل مع المستخدِم حتّى يعلم بالضّبط كيف يعمل السكربت ومالمعلومات الّتي يطلُبها. ليست كلّ السكربتات تحتاج إلى واجهة مستخدِم؛ السكربت الأوّل الّذي كتبناه أسرع من الثّاني وأفضل في كثير من الأحيان. لا تُضِف واجهة استخدام إلّا للسكربتات الّتي يحتاج المستخدِم للمساعدة في استخدامها، في هذه الحالة ستحتاج لأمر echo. التّعليمات الشّرطيّة Conditional statementsتُعدّ التّعليمات الشّرطيّة من الأمور الّتي لا غنى عنها لأيّ لغة برمجة متكاملة. سنتطرّق في هذا الجزء من الدّرس لطريقة وضع شروط وتنفيذ أوامر عند تحقّق - أو عدم تحقّق - هذه الشّروط. 1- أمر ifتُستخدَم التّعليمات الشّرطيّة لوضع شروط تُنفَّذ عند تحقّقها إجراءات معيّنة. يوجد في Shell أمر if الّذي يُتبَع بعبارة ستُختَبَر صحّتها. يُمكن لهذا العبارة أن تكون عبارة منطقيّة، رمز خروج Exit code لأمر أو بعض الأمور الأخرى. عند العمل على رموز الخروج من أوامر فإن استخدامَها مباشِر: if ls folder then echo "Folder exists" fiإذا وُجد ملفّ باسم folder فإنّ السّكربت السّابق سيُنفّذ الأمر echo "Folder exists" لأنّ رمز الخروج من أمر ls في هذه الحالة هو 0 (يُشير الرّمز 0 إلى أنّه لا توجد أخطاء في تنفيذ الأمر). أمّا إذا لم يوجد المجلَّد فلن تُعرَض الرّسالة. يجب أن تتبع كلَّ تعليمة if بthen ,وتُختَم بfi. إذا أردت التّعامل مع عبارات منطقيّة في تعليمة if فستحتاج لأمر test. توجد في Shell العوامل Operators التّاليّة لمقارنة الأعداد: eq-: يُساويne-: لا يُساويlt-: أصغر منle-: أصغر من أو يُساويgt-: أكبر منge-: أكبر من أو يُساويتوجد طريقتان لكتابة أمر test: if test 4 -gt 3أو: if [ 4 -gt 3]تؤدّي الكتابتان نفس العمل تمامًا، كما أنّهما تحتاجان أيضًا لthen وfi. مثال: if [ 20 -lt 10 ] then echo "What?" fiإذا جرّبت تنفيذ السكربت السّابق فستُلاحِظ ألّا شيءَ يُعرَض على الشّاشة؛ لأنّ الشّرط غير متحقّق، فالعدد 20 ليس أصغر من 10. ماذا لو أردنا عرض رسالة للزّائر في حال عدم تحقّق الشرط، مثل ماهو الحال في المثال السّابق؟ 2- أمر elseتُضيف else بديلًا يُنفَّذ عند عدم تحقّق الشّرط في تعليمة if. طريقة الاستخدام: if [ 20 -lt 10 ] then echo "What?" else echo "No, 20 is greater than 10." fiفي هذا المثال نتحقّق من شرط “20 أصغر من 10”، في حال كان صحيحًا نطبع كلمة “?What”، أمّا إذا لم يكن صحيحًا فنطبع عبارة “No, 20 is greater than 10.” (أي لا، 20 أكبر من 10). يُمكن، إلى جانب العبارات المنطقيّة، مفارنة سلسلة محارف ضمن تعليمة if/else. تتطلّب مقارنة المحارف صيغةً مختلفة قليلًا عن مقارنة الأعداد، ولكنّها تسخدم أمر test أيضًا. في ما يلي صيغة مقارنة سلسلة محارِف: string = string: تكون العبارة صحيحة عندما تكون السّلسلتان متساويّتيْنstring != string: تكون العبارة صحيحة عندما لا تكون السّلسلتان متساويّتيْن.string: سلسلة غير خاويّة أو غير معرَّفةn string-: سلسلة معرَّفة وغير خاويّةz string-: سلسلة معرَّفة وغير خاويّةتوجد أيضًا طُرُق لاختبار خصائص الملفّات: s file-: تكون العبارة صحيحة إذا كان الملفّ file غير فارغ.f file-: عبارة صحيحة إذا كان الملفّ file موجودًا وليسd folder-: العبارة صحيحة إذا كان folder مجلّدًا وليس ملفًّا.w file-: عبارة صحيحة إذا كان يُمكن الكتابة في الملف filer file-: يتحقّق الشّرط عندما يكون الملفّ file للقراءة فقط.x file-: تختبر هل الملفّ قابل للتّنفيذ.3- تعليمات if متداخلة Nested if’sيُمكن كتابة تعليمة if كاملة ضمن تعليمة if أخرى، في ما يُعرف بتعليمات if متداخلة. نتعرّف على عمل بتعليمات if المتداخلة في المثال التّالي بالاستعانة بأمر read: #!/bin/bash echo "Input which file you want created" read file if [ -f $file ] then echo "The file already exists" else touch $file if [ -w $file ] then echo "The file was created and is writable" else echo "The file was created but isn't writable" fi fiيطلُبُ السكربت من المستخدِم إدخال اسم ملفّ ليُنشئه، ويخزّن اسم الملفّ في المتغيّر file؛ ثمّ يختبر إن كان الملفّ موجودًا f $file-، ويُظهر رسالة بذلك إن كانت نتيجة التّحقّق إيجابيّة وإلّا يُنشئ الملفّ (touch $file). بعد إنشاء الملفّ يختبر هل يُمكن الكتابة عليه (w $file-) وإذا كانت الإجابة نعم يطبع الرّسالة The file was created and is writable وإلّا يطبع رسالة مغايِرة The file was created but isn't writable. 4- مثال على سكربتنُكمل مع سكربت النّسخ الاحتيّاطي لتحسينه. تتضمّن هذه النّسخة اختبارًا لمعرفة ما إذا كان مجلّد النّسخ موجودًا (d $BACKUPFOLDER-) وما إذا كان لدى المستخدِم امتيّاز Privilege إنشاء مجلّد. نبدأ بإنشاء السّكربت وإعداده: touch ~/bin/filebackup3 chmod +x ~/bin/filebackup3 nano ~/bin/filebackup3ثمّ تحريره: #!/bin/bash #Backup script 3.0 #Description: makes a copy of any given file at the backup folder #Author: Your Name #Date: 9/29/2013 #Request the backup folder from the user: echo -e "\e[47m\e[1m\e[32mFile Backup Utility\n\e[39m\e[0m\e[47mPlease input your backup folder:" read BACKUPFOLDER #The script will make sure the folder exists if [ -d $BACKUPFOLDER ] then echo "You backup folder exists and will be used." else mkdir $BACKUPFOLDER if [ -d $BACKUPFOLDER ] then echo "Backup folder created successfully." else echo -e "I do not have the rights to create your backup folder.\nThis script will now exit." exit 1 #exit 1 is a command that exits the script with an error code fi fi #Request files to be backed up: echo -e "\e[30mWhich files do you want backed up?\e[39m\e[49m" read FILES if [ -n $FILES ] then cp -a $FILES $BACKUPFOLDER else echo "File does not exist." fiلاحِظ أمر exit الّذي يُستخدَم لإيقاف السّكربت مع رمز خطأ. يعرض السّكربت رسالة عندما لا يوجد مجلّد للنّسخ الاحتيّاطيّ، عند إنشائه، إن لم يكن بالإمكان إنشاؤه، وعند كتابة سلسلة محارف خاويّة لأسماء الملفّات. خاتمةيضع هذا الدّرس اللّبنات الأساسيّة الّتي تمكّن من كتابة سكربتات Shell يُمكن للمستخدِم التّفاعل معها. لا زال هناك الكثير لتعلّمه من أجل كتابة برامج Shell بإمكانيّات أكبر وحلول أكثر إبداعًا، إلّا أنّ إتقان المحتوى الموجود هنا خطوة أولى في الطّريق. ترجمة بتصرّف لسلسلة مقالات An Introduction to Shell Scripting