استخدام الأمر المُضمَّن Shift في Bash

من موسوعة حسوب
اذهب إلى: تصفح، ابحث

وظيفة أمر shift

هو أحد أوامر صدفة بورن التي تأتي مع صدفة Bash أيضًا، ويأخذ هذا الأمر وسيطًا (argument) واحدًا ويكون ذلك الوسيط رقمًا، وتُنقل المعامِلات الموضعية إلى اليسار بمقدار هذا الرقم "N"، أما المعامِلات التي تلي ذلك، من 1+N وما بعده إلى #$ فإن أسماءها تُغيَّر إلى أسماء متغيرات من 1$ إلى #$ +1 - N.

فمثلًا لنقل أن لديك أمرًا يأخذ عشرة وسائط، وN تساوي 4، إذًا 4$ تصبح 1$، و 5$ تصبح 2$ وهكذا إلى أن تصل إلى 10$ التي تصبح 7$. أما 1$ و 2$ و 3$ الأُوَل فنستغني عنها.

ولا تتغير المعامِلات الموضعية إن كانت N تساوي صفرًا أو أكبر من #$ ولا يكون للأمر أي تأثير (العدد الإجمالي للوسائط، انظر الاستخدامات المتقدمة لعبارة if الشرطية في Bash)، أما إن لم تكن N موجودة فإن قيمتها تكون 1 افتراضيًا. كذلك تكون حالة الإعادة صفرًا ما لم تكن N أكبر من #$ أو أقل من صفر، وإلا فإنها تكون غير صفرية.

أمثلة

تُستخدم عبارة shift في الغالب عند عدم معرفة عدد وسائط أمر ما مسبقًا، كأن يُسمح للمستخدمين بإدخال أي عدد يرغبون به من الوسائط. وتُعالَج الوسائط في تلك الحالات في حلقة while مع حالة اختبار لـ (( #$ )). وتتحقق هذه الحالة ما دام عدد الوسائط أكبر من الصفر، ويعالج الوسائط كل من متغيرُ 1$ وعبارةُ shift . كذلك يقل عدد الوسائط في كل مرة تُنفَّذ فيها shift إلى أن يصل العدد إلى صفر، عندئذٍ تخرج حلقة while.

يستخدم مثال cleanup.sh أدناه عبارة shift لتعالج كل ملف في القائمة التي أنشأها أمر find:
#!/bin/bash

# يمسح هذا البرنامج الملفات التي لم تُفتح منذ 365 يوم

USAGE="Usage: $0 dir1 dir2 dir3 ... dirN"

if [ "$#" == "0" ]; then
	echo "$USAGE"
	exit 1
fi

while (( "$#" )); do

if [[ $(ls "$1") == "" ]]; then 
	echo "Empty directory, nothing to be done."
  else 
	find "$1" -type f -a -atime +365 -exec rm -i {} \;
fi

shift

done
الفرق بين exec- و xargs
يمكننا استخدام السطر التالي مكان أمر find بالأعلى:
find options | xargs [أوامر_تُنفذ_على_الملفات_التي_سيعثر_عليها_أمر_find]
يبني أمر xargs ويُنفذ أسطر أوامر من مُدخل قياسي (standard input)، وميزة ذلك أن سطر الأوامر يُملأ حتى أقصى حد يتحمله النظام، وعندئذ فقط تُستدعى الأوامر التي يجب تنفيذها. وفي المثال السابق فإن ذلك الأمر الذي يجب تنفيذه هو rm، وإن كانت هناك وسائط أخرى فيُستخدم سطر أوامر جديد حتى يكتمل أو حتى تنتهي الوسائط. أما أمر find -exec فإنه يستدعي الأمر الذي يجب تنفيذه على الملفات التي وُجدت في كل مرة يوجد فيها ملف. وبهذا ترى أن استخدام xargs يسرِّع برنامجك وأداء حاسوبك.
انظر المثال التالي حيث عدّلنا البرنامج الذي استخدمناه في مستندات Here من صفحة الحصول على مُدخلات المستخدم في Bash كي يقبل تثبيت عدة حزَم مرة واحدة:
#!/bin/bash
if [ $# -lt 1 ]; then
        echo "Usage: $0 package(s)"
        exit 1
fi
while (($#)); do
	yum install "$1" << CONFIRM
y
CONFIRM
shift
done

انظر أيضًا

مصادر