برخی از فرمانهای کنترل job زیرین، یک معرف job را به عنوان شناسه دریافت میکنند. جدول انتهای این فصل را ملاحظه کنید.
این فرمان، jobهای در حال اجرای پسزمینه را با ارایه شماره job آنها، لیست میکند. به اندازه ps سودمند نیست.
jobها و پردازشها بسیار به آسانی با یکدیگر اشتباه گرفته میشوند. برخی builtinها، از قبیل kill، disown، و wait یک شماره job یا یک شماره پردازش را به عنوان شناسه میپذیرند. فرمانهای fg، bg، و jobs فقط یک شماره job را قبول میکنند.
bash$ sleep 100 & [1] 1384 bash $ jobs [1]+ Running sleep 100 & «1» شماره job است (jobها توسط پوسته جاری نگهداری میشوند). «1384» شماره ID پردازش یا PID است (پردازشها توسط سیستم نگهداری میشوند). برای کشتن این job/پردازش، یا یک kill %1 یا یک kill 1384 عمل میکند. باتشکر از S.C. |
job(ها) را از جدول jobهای فعال پوسته حذف میکند.
فرمان fg یک job در حال اجرا در پسزمینه را به پیشزمینه تغییر وضعیت میدهد. فرمان bg یک job تعلیق شده را دوباره شروع کرده و آن را در پسزمینه اجرا میکند. در صورتیکه شماره job تعیین نشده باشد، آنوقت فرمانهای fg یا bg بر روی job در حال اجرای جاری عمل میکنند.
اجرای اسکریپت را تا زمانیکه تمام jobهای در حال اجرای پسزمینه خاتمه یافته باشند، یا job و پردازشی که شمارهاش به عنوان یک گزینه فرمان مشخص گردیده خاتمه یابد، به تعلیق در میآورد. سپس وضعیت خروج فرمانی را که در انتظارش مانده برگشت میدهد.
شما ممکن است فرمان wait را برای پیشگیری از خروج اسکریپت قبل از اتمام اجرای یک job پسزمینه (چنین خروجی یک پردازش پدر مرده نگرانکننده تولید خواهد کرد) به کار ببرید.
مثال 15-26. انتظار برای پایان یافتن یک پردازش، قبل از پیشروی
#!/bin/bash ROOT_UID=0 #فقط کاربرانِ با $UID برابر 0 دارای مزایای root هستند. E_NOTROOT=65 E_NOPARAMS=66 if [ "$UID" -ne "$ROOT_UID" ] then echo "Must be root to run this script." #«بچه برو پی کارت، از موقع خوابت گذشته است.» exit $E_NOTROOT fi if [ -z "$1" ] then echo "Usage: `basename $0` find-string" exit $E_NOPARAMS fi echo "Updating 'locate' database..." echo "This may take a while." updatedb /usr & #باید به عنوان root اجرا شود. wait #تا وقتی که updatedb پایان یابد، بقیه اسکریپت اجرا نشود. #قبل از جستجوی نام فایل، بانک اطلاعات به روزرسانی شده را لازم دارید. locate $1 #بدون فرمان wait، در یک وضعیت وخیمتر، در حالیکه updatedb هنوز در حال #+ exit 0
wait میتواند به طور اختیاری یک معرف job را به عنوان یک شناسه دریافت کند، به عنوان مثال، wait %1 یا wait $PID [1]. جدول job id را ملاحظه کنید.
در درون یک اسکریپت، اجرای یک فرمان در پسزمینه به وسیله یک کاراکتر ampersand (&) ممکن است موجب شود که اسکریپت تا زدن کلید ENTER هنگ شود. به نظر میرسد این مورد با فرمانهایی اتفاق میافتد که در stdout مینویسند. این میتواند یک دردسر مهم باشد. #!/bin/bash # ls -l & echo "Done." bash$ ./test.sh Done. [bozo@localhost test-scripts]$ total 1 -rwxr-xr-x 1 bozo bozo 34 Oct 11 15:09 test.sh _ به طوری که Walter Brameld IV آن را تشریح میکند: ظاهراً چاره این مشکل، قرار دادن یک فرمان wait بعد از فرمان پسزمینه است. #!/bin/bash # ls -l & echo "Done." wait bash$ ./test.sh Done. [bozo@localhost test-scripts]$ total 1 -rwxr-xr-x 1 bozo bozo 34 Oct 11 15:09 test.sh bash$تغییر مسیر خروجی فرمان به یک فایل یا حتی به /dev/null نیز این مشکل را برطرف میکند. |
این فرمان دارای اثری مشابه Control-Z است، اما پوسته را به حالت تعلیق در میآورد (پردازش والد پوسته باید در یک زمان مناسب آن را ادامه بدهد).
خروج یک پوسته login، به طور اختیاری با مشخص کردن یک وضعیت خروج.
آماری در باره زمان صرف شده سیستم برای اجرای فرمانها، در قالب زیر ارایه میکند:
0m0.020s 0m0.020s
این توانایی ارزش نسبتاً محدودی دارد، چون برای شناسایی و سنجش کارایی اسکریپتهای پوسته رایج نیست.
خاتمه دادن اجباری یک پردازش به وسیله فرستادن یک سیگنال فسخ متناسب ( مثال 17-6 را ببینید).
مثال 15-27. اسکریپتی که خودش را میکُشد
#!/bin/bash # self-destruct.sh kill $$ # #به خاطر بیاورید که $$ برابر با PID اسکریپت است. echo "This line will not echo." # exit 0 #خروج عادی است؟ خیر! # #+ #bash$ sh self-destruct.sh bash$ echo $? 143# #
kill -l تمام سیگنالها را لیست میکند (همانطور که فایل /usr/include/asm/signal.h لیست میکند). یک kill -9 یک kill حتمی است، که معمولاً به پردازشی که سرسختانه از کُشته شدن با یک kill ساده خودداری میکند، خاتمه میدهد. گاهی اوقات، kill -15 نیز عمل میکند. یک پردازش zombie، یعنی یک پردازش فرزند که خاتمه یافته، اما پردازش والدش هنوز آن را kill نکرده است، نمیتواند به وسیله یک کاربر login کرده kill بشود -- شما نمیتوانید چیزی را قبلاً مُرده از بین ببرید -- اما init دیر یا زود آن را تصفیه خواهد نمود. |
فرمان killall یک پردازش در حال اجرا را به جای کشتن بواسطه ID پردازش، بواسطه نام از بین میبرد. اگر چند نمونه از یک فرمان خاص در حال اجرا، وجود داشته باشد، آنوقت یک killall روی آن فرمان، همه آنها را خاتمه خواهد داد.
این دستور به فرمان killall در /usr/bin ارجاع میکند، نه به اسکریپت killall در |
دستور command مستعارها و توابع را برای فرمانی که بلافاصله به دنبال آن میآید، از کار میاندازد.
bash$ command ls
فراخوانی builtin BUILTIN_COMMAND فرمان BUILTIN_COMMAND را به عنوان یک builtin پوسته اجرا میکند، به طور موقت فرمانهای خارجی سیستم و توابع با همان نام را از کار میاندازد.
این یک فرمان builtin پوسته را فعال یا غیرفعال میکند. به عنوان یک مثال، enable -n kill فرمان builtin پوسته با نام kill را غیرفعال میکند، به طوریکه وقتی Bash پس از آن با kill روبرو شود، فرمان خارجی /bin/kill را احضار میکند.
گزینه -a با enable تمام builtinهای پوسته را با نشان دادن اینکه آیا فعال هستند یا خیر، لیست میکند. گزینه -f filename اجازه میدهد که enable یک builtin را از یک فایل object کامپایل شده، به صورت یک ماژول کتابخانهای به اشتراک گذاشته شده (DLL) بارگیری نماید [2].
این یک تبدیل Bash از autoloader پوسته ksh است. با کاربرد مناسب autoload، تابعی با یک اعلان autoload، در اولین احضارش، از یک فایل خارجی بارگیری خواهد گردید. [3] این کار منابع سیستم را صرفهجویی میکند.
توجه نمایید که autoload بخشی از هسته مرکزی برپاسازی Bash نیست. لازم است به وسیله enable -f در آن بارگذاری بشود (بالا را ببینید).
جدول 15-1. (تعیین هویت کننده)معرفهای Job
نماد | معنی |
---|---|
%N | شماره Job [N] |
%S | فراخوانی (در خط فرمان) job شروع شوند با رشته S |
%?S | فراخوانی (از خط فرمان) job شامل رشته S در داخل نام آن |
%% | job «جاری» (آخرین job متوقف شده در پیشزمینه یا شروع شده در پسزمینه) |
%+ | job «جاری» (آخرین job متوقف شده در پیشزمینه یا شروع شده در پسزمینه) |
%- | آخرین job |
$! | آخرین پردازش پسزمینه |
[1] | البته، این فقط برای پردازشهای فرزند صادق است. |
[2] | به طور نمونه، کد منبع C تعدادی از builtinهای قابل بارگذاری، در دایرکتوری /usr/share/doc/bash-?.??/functions قرار دارد. توجه کنید که گزینه -f با enable قابل حمل به تمام سیستمها نیست. |
[3] | همان نتیجه autoload میتواند به وسیله typeset -fu حاصل گردد. |