استخدام الأمر المُضمَّن 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