لینوکس برای همه
سرجمع دو نوع دستور در پوسته وجود دارد: یک سری دستورهای «معمولی» هستند که میشود از خط فرمان ( Command Prompt ) هم آنها را اجرا کرد (که به آنها دستورات خارجی هم گفته میشود)، و یک سری دستور «از پیش تعیین شده» هم وجود دارد که (دستورات داخلی نامیده میشود) پیشتر به آنها اشاره شد.
دستورات داخلی نمیتوانند بهعنوان برنامه فراخوانده شوند. البته، چندان هم مهم نیست که یک دستور داخلی است یا خارجی؛ جز اینکه دستورات داخلی بهتر اجرا میشوند. در این بخش، تنها دستورات مهم خارجی و داخلی را بررسی خواهیم کرد.
اگر کاربر لینوکس هستید، بهطور قطع دستورات دیگری را میدانید که میشود در خط فرمان بهکار برد، پس میتوانید از آنها هم در اسکریپت پوسته خود بهره بگیرید.
break
دستور < break>برای فرار از حلقههای بسته for ، while و until بهکار میرود. میتوانید با break چند بار از حلقه فرار کنید، اما اینکار باعث میشود تا خوانایی اسکریپت پایین بیاید، و پیشنهاد نمیشود. تنها کافیست بدانید که بهطور پیشفرض، break از یک سطح (یک دور) حلقه فرار میکند.
:
دستور <:> (دونقطه، کولن) دستور پوچی است. اغلب برای ساده کردن منطق عبارات بهکار میرود و صورت دیگری برای true است. چون دستور تعبیه شدهای است، پس از true سریعتر اجرا میشود، هرچند خروجی کار کمتر خواناست. ممکن است در عباراتی مانند while: آن را مشاهده کنید که در واقع، بهجای while true مینشیند و منظور همان حلقه نامتناهی همیشگی است، اما پرکاربردتر است.
دستور دو نقطه در مقداردهی به متغیرها نیز بهکار میآید، مثلا در دستور:
ت$تvar:=value:
بدون حضور:، پوسته سعی میکند $var را بهعنوان یک دستور اجرا کند.
نکته:در اسکریپتهای پوستههای قدیمی، ممکن است نگاهتان به کولنی بیفتد که ابتدای خط شروع شده است. آن برای کامنت گذاشتن است، اسکریپتهای مدرنتر برای ایجاد خط کامنت از استفاده میکنند، بههمان دلیل اجرا شدن سریعتر.
continue
درست همانند همنام این دستور در زبان C، این دستور از حلقههای for، while یا until خارج میشود و حلقه را به دور بعدی میفرستد و متغیر حلقه مقدار بعدی خود را میگیرد.
َ!/bin/sh
rm -rf fred*
1fred 2fred 3mkdir fred
4fred for file in fred*
do
if [ -d “$file”]; then
echo “skipping directory $file”
continue
fi
file$echo file is
done
rm -rf fred*
0exit
continue میتواند عدد شمارنده حلقه را بهعنوان پارامتر انتخابی بگیرد تا بتوانید از بخشی از حلقه تو در تو بیرون بروید. این کار هم بهندرت استفاده میشود و باعث میشود تا اسکریپت شما سختتر فهمیده شود. برای مثال:
3 2 1for x in
do
x$echo before
1continue
x$echo after
done
خروجی زیر را خواهد داد:
1before
2before
3before
.
دستور < . > (نقطه، دات)، دستوری را در همین پوسته اجرا میکند:
shell-script/. .
اغلب، وقتی یک اسکریپت دستور خارجی یا اسکریپتی را اجرا میکند، محیطی جدید (Subshell) ، یا زیرپوسته ایجاد میشود و دستور در محیط جدید اجرا میشود و آن محیط با کد خروجیای که از اجرای اسکریپت حاصل میشود، بسته شده و کد را به پوسته والد بر میگرداند.
هرچند دستور خارجیsource و دستور نقطه دستوراتی که در یک اسکریپت همان پوسته قرار دارند را اجرا می کند. چون بهطور پیشفرض با اجرای یک اسکریپت پوسته، محیط جدیدی ایجاد میشود، هر تغییری که اسکریپت در متغیرهای محیطی ایجاد کند، نابود میشوند.
از طرف دیگر دستور نقطه اجازه میدهد اسکریپت اجرا شده محیط فعلی را تغییر دهد. این کار هنگام استفاده از اسکریپتی که به عنوان Wrapper (پوشا) برای تنظیم محیط فعلی بهمنظور اجرای دستورات بعدی بهکار میرود، بسیار مفید است.
مثلا وقتی دارید روی چند پروژه بهصورت همزمان کار میکنید، احتمالا به خودتان میآیید و میبینید دارید دستورات را با پارامترهای مختلفی فراخوان میکنید و لابد نسخه کامپایلر قدیمی را برای راهاندازی برنامههای قدیمی مدام صدا میزنید.
در اسکریپتهای پوسته، دستور نقطه کمی شبیه شبهکدinclude درC یاC++ عمل میکند. هرچند که در حقیقت اسکریپت را include نمیکند، دستورات را در همین محیط اجرا میکند و بههمین دلیل، شما میتوانید از این دستور برای مجتمعسازی متغیرها و تعریف توابع در یک اسکریپت استفاده کنید.
echo
صرفنظر از استفاده printf در پوستههای مدرن، تا همین الان مثالها را با استفاده از دستور echo برای چاپ یک رشته، که بهدنبالش کاراکتر خط جدید دارد، حل کردیم. منتها، مشکل اینجاست که نسخههای مختلف UNIX راهحلهای مختلفی برای اینکار (چسبانیدن کاراکتر خط جدید به انتهای رشته چاپی) دارند، اما عموما این دستور جوابگو است و نیازی به مراجعه به راهنمای دستور ندارید:
echo n “String To Output”
eval
دستور eval شما را قادر میسازد تا دستورات را مقدار دهی کنید. این دستور تعبیه شده است و نمیتوان بهعنوان دستور خارجی از آن استفاده کرد. بهترین و واضحترین مثالی که میتوان از این دستور آورد، همانی است که در صفحه راهنمای آن آورده شده:
10foo=
x=foo
x”$”$y=
y$echo
واضح است که این دستور خروجی $foo را میدهد، اما این جا را نگاه کنید:
10foo=
x=foo
x”$”$eval =y
y$echo
خروجی 10 را میدهد. انگارeval یک جورهایی شبیه یک $ اضافه باشد: مقدارِ مقدارِ یک متغیر را به ما میدهد. دستورeval خیلی مفید است، باعث میشود کد ایجاد شده و روی هوا (on-the-fly) اجرا شود. دیباگ آن سخت میشود اما باعث میشود کارهایی که پیادهسازیشان جور دیگر سخت یا حتا غیرممکن است، بهسادگی پیاده کرد.
exec
دستور < exec >دو کاربرد مختلف دارد. کاربرد معمولاش جایگزینی پوسته فعلی با برنامه دیگری است. برای مثال:
Exec wall “thanks for all the fish”
را اگر در یک پوسته بهکار ببریم، پوسته فعلی را با دستور wall جایگزین میکند. هیچ خطی در اسکریپت بعد از دستور exec اجرا نمیشود، چرا که پوستهای که اسکریپت ما را ایجاد میکرد دیگر وجود ندارد.
راه حل دوم استفاده از exec تغییر توضیحدهندههای فایل است. برای نمونه:
> afile3exec
باعث میشود که توضیحدهنده فایل 3 باز شود تا از فایلafile بخواند. این دستور بهندرت بهکار میآید.
exit n
دستور باعث میشود تا اسکریپت با کد خروجیn خارج شود. اگر در خط فرمان هر پوستهای اجرایش کنید، شما را از سیستم بیرون میفرستد. اگر به اسکریپت خود اجازه بدهید که بدون هیچ کدی که نشانگر وضعیت خروج باشد، دستورexit را اجرا کند، در اینصورت کد وضعیت آخرین دستور اجرا شده در اسکریپت بهعنوان مقدار بازگشتی مورد استفاده قرار میگیرد. استفاده از کد خروجی همیشه تمرین خوبی است و باید عادت بشود.در برنامهنویسی اسکریپت پوسته، کد خروجی 0 یعنی موفقیت، و کدهای 1 تا 125، کدهای خطایی هستند که در اسکریپتها میتوان از آنها استفاده کرد. مقادیر باقیمانده معنای رزرو شده دارند، جدول زیر را ببینید:
استفاده از 0 برای خروجی موفقیت آمیز، شاید برای کاربران C یا C++ کمی عجیب بهنظر برسد. ویژگی خوبی که در اسکریپتها به چشم میآید، این است که میتوانید از 125 کد تعریفی توسط کاربر بدون احتیاج به متغیر عمومی(global) استفاده کنید.
export
دستور باعث میشود متغیرها درsubshell ها نیز بتوانند استفاده شوند. بهطور پیشفرض هیچ متغیری در یک پوسته نمیتواند داخل پوستهsubshell/ های دیگر بهکار گرفته شود. دستورexport از پارامترهای خود متغیر محیطی درست میکند که بتوانند در اسکریپتها و برنامههای دیگری که از برنامه فعلی فراخوانده میشوند، مورد استفاده قرار بگیرند. اگر بخواهیم فنیتر بگوییم، متغیرهای صادر شده متغیرهای محیطی هر پروسس فرزندی را که از پوسته ایجاد شده تشکیل میدهند. بیایید یک مثال را ببینیم:
فایل2export
َ!/bin/sh
“foo$”echo
“bar$”echo
فایل1export
َ!/bin/sh
”The first meta-syntactic variable”foot=
The second meta-”export bar=
”syntactic variable
2export
اگر این اسکریپت را اجرا کنیم، خروجی اینطوری میشود:
1./export$
The second meta-syntactic variable
$
کد خروجی شرح
126 فایل قابل اجرا شدن نیست
127 دستور یافت نشد
128و بالاتر سیگنالی رخ داد