به طور معمول به پردازش با استفاده از شماره شناسایی پردازش(PID) رجوع میشود، و فرمان ps(1) میتواند اطلاعات هر پردازشی با شماره شناسایی (ID) داده شده را نمایش بدهد، به عنوان مثال
$ echo $$ # شماره شناسایی پردازش من 21796 $ ps -p 21796 PID TTY TIME CMD 21796 pts/5 00:00:00 ksh
اما خیلی اوقات شماره شناسایی یک پردازش معلوم نیست، بلکه فقط نام آن مشخص میباشد. بعضی سیستم عاملها، به عنوان مثال سولاریس، BSD، و برخی نگارشهای لینوکس، دارای یک دستور اختصاصی برای جستجوی پردازشی با نام معلوم میباشند، که pgrep(1) نامیده شده است:
$ pgrep init 1
حتی اغلب یک برنامه تخصصیتر نه تنها برای یافتن ID پردازش یک فرآیند با نام معین، بلکه همچنین برای ارسال سیگنال به آن پردازش، در دسترس میباشد:
$ pkill myprocess
بعضی سیستمها pidof(1) را نیز فراهم نمودهاند. این با pgrep در آن،شماره شناساییهای پردازش چندتاییِ خروجی، فقط با فاصله از هم جدامیشوند نه با سطر جدید، تفاوت دارد زیرنویس مترجم 1 .
$ pidof cron 5392
اگر این برنامهها در دسترس نیستند، کاربر میتواند خروجی فرمان ps را با استفاده از grep جستجو نماید.
مشکل عمده موقع استفاده از grep با خروجی فرمان ps آنست که grep ممکن است با مدخل ps خودش منطبق شود(این مورد را امتحان کنید: ps aux | grep init). برای وخیمتر شدن موضوع، این در هر نوبت اجرا اتفاق نمیافتد، نام فنی این مورد RaceCondition است. برای اجتناب از آن چند روش موجود است:
ps aux | grep name | grep -v grepتمام سطرهای شامل "grep" را از خروجی پاک میکند. اشکال: همیشه وضعیت خروج grep -v را خواهید داشت، بنابراین به عنوان مثال نمیتوانید وجود یک پردازش خاص را بررسی کنید.
ps aux | grep -v grep | grep nameاین دقیقاً همان کار را انجام میدهد، به استثنای آنکه وضعیت خروج "grep name" قابل دستیابی است و نشان دهنده «name پردازشی از ps هست» یا «name پردازشی از ps نیست» میباشد. هنوز اشکال شروع یک پردازش جدید(grep -v) را دارد.
ps aux | grep [n]ame
این مورد فقط پردازش grep مورد نیاز را تولید میکند. رمز آن در کاربرد کلاس کاراکتر [] است(عبارتهای منظم). قرار دادن تنها یک کاراکتر در گروه کاراکتری معمولاً به هیچ وجه معقول نیست، زیرا [c] همیشه با یک "c" تطبیق میکند. در این حالت، نیز همانطور است. grep [n]ame کلمه "name" را جستجو میکند. اما چون پردازش متعلق به خود grep مدخلی را لیست میکند که شما اجرا نمودهاید("grep [n]ame") و "grep name" نیست، با خودش منطبق نمیشود.
تمام موارد فوق موقعی صحیح است که شما در اعلان محاورهای پوسته باشید، اما نباید در اسکریپت استفاده شود. خیلی غیرقابل اطمینان است.
اکثر اوقات موقعی که شخصی چنین سؤالی میپرسد، به دلیل آنست که میخواهد با تکنیکهای ابتدایی اسکریپتنویسی یک daemon را مدیریت نماید. انواع همگانی این پرسشها عبارتند از: « چگونه میتوانم PID فلان پردازش خود را به دست آورم....به طوری که اگر آن پردازش از قبل در حال اجرا نباشد آن را شروع کنم» یا «چطور میتوانم PID بَهمان پردازش خود را به دست آورم... چون میخواهم در صورتیکه از قبل فعال شده است از اجرای آن توسط اسکریپت اجتناب نمایم.» این پرسشها هر دو به طور خطرناکی منجر به ایجاد ضعف سیستم میگردند.
اگر به راستی آنچه میخواهید، آن است که هر وقت daemon مورد نظرتان میمیرد، شروع مجدد بشود، فقط این کار را انجام بدهید:
while true; do mydaemon --in-the-foreground done
که در آن --in-the-foreground گزینهای است که اگر وجود داشته باشد، باید به daemon داده شود تا از بردن خودش به طور خودکار به پس زمینه اجتناب نماید. (اغلب، -d این کار را انجام میدهد و سودمندی بیشتری از اجرای daemon با تفصیلنویسی افزایش یافته را دارد.) برنامههایی کهdaemonها را در خود دارند ممکن است آماج بعدی لفاظی greycat باشند یا نباشند....
اگر این خیلی سادهلوحانه است، به daemontools یا runit که برنامههایی برای مدیریت سرویسها میباشند، نگاه کنید.
اگر واقعاً آنچه شما میخواهید پیشگیری از اجرای چند نمونه از برنامه خودتان است، آنوقت تنها روش مطمئن انجام آن، کاربرد یک قفل است. برای تفصیل بیشتر در مورد انجام این کار، بخش مدیریت پردازش یا پرسش و پاسخ شماره 45 را ببینید.
مدیریت پردازش، مباحثی مانند«من میخواهم گروه job خود را به 5 رشته تقسیم نموده و تمام آنها را به طور موازی اجرا نمایم.» را هم پوشش میدهد. لطفاً آن را بخوانید.
$pidof getty 1836 1083 1034 1025 1006 999 $pgrep getty 999 1006 1025 1034 1083 1836(1)
پرسش و پاسخ 33 (آخرین ویرایش 2009-12-30 18:39:04 توسط MatthiasPopp)