در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

آموزش گام به گام لینوکس قسمت 3 : دستورها چگونه اجرا می شوند؟

در این مقاله می خواهم به چندین موضوع که به عنوان یک کاربر لینوکسی یا مدیر لینوکس بدانید صحبت کنم. در اینجا نمی خواهم درباره دستور ها و معرفی آنها صحبت کنم بلکه نگاهی اجمالی به اجرای یک دستور خواهم پرداخت. در مفاهیم سیستم عامل برنامه یا Program را واحد غیرفعال یا Passive Unit و فرایند یا Process را واحد فعال یا Active Unit گویند و این از این جهت است که وقتی برنامه ای مانند واژه پرداز مثل word را نصب می کنید مجموعه ای فایل ها، کتابخانه ها است که همان تعریف برنامه است.. اما واحد فعال آن فرایند است که با کاربر در تعامل است. همانطور که در بخش نخست از مطلب گام به گام با لینوکس گفتم، در لینوکس گونه ای از فرایند ها به نام Background Process یا daemon وجود دارد که هیچگونه تعاملی با کاربر ندارند. زمانی که ایجاد می شوند در پس زمینه به درخواست های ورودی گوش می دهند.

اما دسته دیگری از فرایند ها هستند که با کاربر در تعامل هستند. به طور مثال ویرایشگر متنی یا word دارای فرآیندی هستند که کاربر با آن در تعامل است. ورودی ها (کاراکتر، درج تصاویر، درج جدول و غیره) را از کاربر گرفته و عمل لازم را انجام می دهند. هر دو گونه فرایند گفته شده (تعاملی و غیر تعاملی) واحد فعال هستند. اما فعال بودن یعنی چی؟ یعنی اینکه فریاند ها برای اجرا شدن به حافظه اصلی نیاز دارند و در آن زمانبندی شده و بر اساس مکانیزم هایی پردازنده را گرفته و اجرا می شوند. اما برنامه که فایل ها است نیازی به اجرا شدن ندارند.

همچنین فریاند ها دارای حالت هستند که از این بحث خارج است.امروزه فرایند ها در قالب چند نخ یا Thread ایجاد می شوند. فرض کنید یک برنامه کاربردی بزرگ دارید که باید چندین پردازش یا عمل را انجام دهد. برای مثال همان word که اگر فرایند آن تک نخی بود باید هر درخواست یا تعامل کاربر را پاسخ داده و سپس به سراغ کار یا تعامل و درخواست بعدی برود. اما با چند نخی بودن فرایند، هر نخ یک وظیفه را انجام می دهد.

یکی ورودی ها را گرفته و دیگری همزمان چیدمان فایل را تنظیم می کند. به هر حال برای ادامه لازم بود مفاهیم بالا گفته شود. در لینوکس نخستین فرایندی که توسط خود هسته و با مالکیت کاربر مدیر یا root ایجاد می شود فرایند init نام دارد. init نخستین فرایند و با شناسه 1 است که بقیه فرایند ها را ایجاد می کند. init پس از ایجاد شدن اقدام به ایجاد فرایند های پس زمینه ای می کند که سرویس هایی مانند ssh, dns, dhcp را ایجاد می کند. همچنین فرایند هایی که بر ورود کاربران (لاگین) به سیستم یا کنترل رابط گرافیکی را نیز ایجاد می کند. همچنین هر کدام به ترتیبی که ایجاد می شوند یک شناسه می گیرند. مثلا سرویس sshd شناسه 140 را می گیرد.


پس فرض می کنیم که init ایجاد شد و ما هم به سیستم لاگین کردیم و تمامی فرایند های پس زمینه ایجاد شده اند. به طور مثال فرایندی که سرویس ssh را کنترل می کند به نام sshd و دارای شناسه 140 است. حال شما می خواهید که از طریق آن به ماشین راه دور متصل شوید. لازم است که یک مفهوم دیگر به نام fork را توضیح دهم. در سیستم عامل های یونیکسی مثل لینوکس fork برای ایجاد یک فرایند عینی از فرایند دیگر استفاده می شود.

فرایند جدید ایجاد شده را فرزند و فرایندی که از آن ایجاد شده است را والد گویند. یک ساختار درختی و سلسله مراتبی میان فرایند ها وجود دارد. والد از روی خودش یک فرزند ایجاد کرده و فرزند نیز از روی خودش فرزند دیگری ایجاد کرده است. در این ساختار درختی نیا یا جد همه ی فرایند ها همان init با شناسه 1 است. دستور pstree را اجرا کنید متوجه منظور من از سلسله مراتبی و جد بودن init خواهید شد.به هر حال شما قصد اتصال را از طریق سرویس ssh دارید.

پس دستور ssh را اجرا کرده اید و در اینجا فرایند یا daemon به نام sshd در حال گوش دادن است و به محض دریافت یک درخواست برای اتصال یک فرایند جدید عین خود (فرزندی از روی خودش) را با شناسه ای متفاوت ایجاد می کند و دروخواست را به آن واگذاری می کند. حال در خروجی دستور top شما دو فرایند sshd با شناسه های مختلف خواهید دید. اما چگونه بفهیم کدام فرایند میان دو فرایند sshd والد است.

البته ممکن است شما بر اساس کاری که انجام دادید بیشتر از دوفرایند هم ببینید. به هر حال فرایند والد دارای یک فایل در زیر دایرکتوری var//run// است. دستور زیر محتوای این فایل را برای فریاند سرویس ssh نشان می دهد. (برای دیگر سرویس ها نیز فایلی وجود دارد)

cat /var/run/sshd.run

در صورتی که فرایند والد را از بین ببرید به خودی خود تمامی فرزندانش از بین خواهند رفت. خوب است بدانید هر گز نمی توانید init را از بین ببرید زیرا سیستم از کار خواهد افتاد. در لینوکس مکانیزمی تعبیه شده است که با kill کردن فرایند init به صورت خودکار و بلافاصله init با همان شناسه یک ایجادخواهد شد. پس از مفاهیم بالا لازم است که چند مطلب دیگر نیز گفته شود. وقتی دستوری را در خط فرمان اجرا می کنید به چند دلیل ممکن است خطا رخ دهد :

  1. دستور را اشتباه نوشته اید. اگر دستور sl را به جای ls بنویسید قطعا خطا است و خطای Command not found نشان داده می شود. در یونیکس بر خلاف ویندوز کوچکی و بزرگی حروف مهم است و میان ls و Ls تفاوت وجود دارد. اولین دستور منجر به فهرست کردن محتویات دایرکتوری و دومین دستور چون غلط است پس از نظر سیستم وجود نداشته و Command not found چاپ می شود.
  2. دستور را اصلا نصب نکرده اید. در اینجا هم Command not found نشان داده می شود.
  3. مسیر دستور در مسیر موجود در متغیر PATH$ کاربر وجود ندارد. PATH متغیری است که به مسیر دستور ها برای کاربر اشاره می کند. دایرکتوری usr//bin// شامل تمامی دستور های عمومی است و sbin// شامل دستور های مدیریتی است. کاربر دستور را اجرا کرده که مسیر آن در متغیر PATH$ وجود ندارد. برای مشاهده محتوای متغیر دستور echo $PATH را اجرا کنید. توجه کنید که متغیر ها در لینوکس با $ شروع می شوند.
  4. کاربر دستوری را اجرا کرده است که اجازه اجرای آنرا ندارد. برای مثال کاربری معمولی دستور fdisk //dev//sdc را برای پارتیشن بندی هارد اجرا کند. در این حالت نیز خطا نشان داده می شود. از طرفی دستوری مانند passwd به کاربر اجازه می دهد که تا تنها گذرواژه خودش را عوض کند و اگر بخواهد گذرواژه دیگری را عوض کند پیغام خطا نشان داده می شود. در لینوکس و دیگر سیستم عامل های یونیکسی از دستور sudo برای اجرای یک دستور با مجوز root استفاده می شود. فرض کنید می خواهید بسته ای را در لینوکس ابونتو نصب کنید پس دستور apt-get install package را وارد می کنید. اگر root نباشید قطعا خطا نشان داده خواهد شد. پس از sudo برای اجرای دستور مدیریتی توسط یک کاربر دیگر استفاده می شود. sudo به نوعی به کاربران یا گروه مجوز اجرای دستور را می دهد. به طور مثال گروهی از دستور های مدیریت دیسک ها را انتخاب کرده و سپس در فایل etc//sudoers// این گروه دستور ها را تعریف و سپس این گروه تعریف شده را به کاربر یا گروهی از کاربران اعطا می کنید. از این پس کاربر با وارد کردن گذرواژه خودش دستور های همان گروه را اجرا می کند.

از طرفی دستوری به نام su نیز وجو دارد که با آن می توانید از خط فرمان به عنوان کاربر دیگری لاگین کنید. یعنی شما با نام کاربری خود وارد شده اید و سپس دستور su - root را در ترمینال وارد کرده و از این پس می توانید کلیه دستور ها را اجرا کنید. اما این کار کاملا اشتباه و خطر ناک است چون گذرواژه root را به دیگری داده ایم و همین تفاوت میان sudo و su است که با sudo و دسته بندی دستور ها و اعطای آنها به کاربر، از این پس کاربر با سطح دسترسی root و با پسورد خودش گروه دستور ها را اجرا می کند.

همچنین می توانید به کاربری اجازه دهید که تمامی دستور ها را با sudo و پسورد خودش همانند root انجام دهد. یعنی هر دستوری را مانند root اجرا کند ولی بازهم با گذرواژه خودش و نه بگفتن گذرواژه root به کاربر. در لینوکس و دیگر یونیکس ها فرمت کلی دستور ها به صورت زیر است

command options args

در اینجا ممکن است option را نادرست وارد کرده باشید یا اینکه مقدار یا args نادرست و نامعتبر را به option داده باشید. در این حالت نیز خطا نشان داده می شود. امیدوارم این مطلب درکی از چگونگی اجرای فرامین لینوکسی را به شما داده باشد.

نویسنده : امیر احمدی نامی
منبع : انجمن حرفه ای های فناوری اطلاعات ایران
هرگونه نشر و کپی بدون ذکر منبع دارای اشکال اخلاقی است
#آموزش_مفاهیم_لینوکس #Shell_در_لینوکس #استفاده_از_لینوکس #مفاهیم_لینوکس #روش_اجرای_دستورات_در_لینوکس #آموزش_مقدماتی_لینوکس #دستورات_در_لینوکس #آموزش_لینوکس #دستور_های_لینوکس #گام_به_گام_با_لینوکس
عنوان
1 آموزش گام به گام لینوکس قسمت 1 : لینوکس چیست ؟ رایگان
2 آموزش گام به گام لینوکس قسمت 2 : آموزش نصب لینوکس رایگان
3 آموزش گام به گام لینوکس قسمت 3 : دستورها چگونه اجرا می شوند؟ رایگان
4 آموزش گام به گام لینوکس قسمت 4 : لینوکس را از کجا شروع کنیم؟ رایگان
زمان و قیمت کل 0″ 0
6 نظر
محمد نصیری

خیلی عالی بود مهندس لذت بردم ، یه نکته ای هست که شما فرمودید با Kill کردن Parent Process یا فرآیند والد ، Child Process ها یا فرآیند های فرزند به صورت پیشفرض از بین میرن ، اما ما شرایطی رو داریم که سیستم عامل ممکنه اینکار رو نتونه انجام بده و با از بین رفتن Parent Process ها Child Process ها از بین نرن ، در ویندوز اگر در Task Manager دقت کنید ما برای End Task کردن Process دو گزینه داریم ، یکی به عنوان End Processو یکی با عنوان End Process Tree که دقیقا بیانگر همین موضوع هستند ، ما در حوزه ای از امنیت در خصوص همین Process ها صحبت داریم که به Process های بی پدر مادر ( این لفظ خودم بود D: ) یا Zombie Process معروف هستند ، یعنی Process هایی که Parent اونها Kill شده اما هنوز Child ها Kill نشدند ، عالی بود لذت بردم ...

امیر احمدی نامی

شما لطف دارید و بنده رو شرمنده می کنید.

اطلاعات زیر رو قبلن از ویکی پدیا خونده بودم و دو نوع فرایند خاص رو به صورت زیر تعریف کرده بود.

یک سری فرایند که Orphan process یا فرایند های یتیم نام دارند این طور هستن که فرایند والد خاتمه یافته ولی فرانید فرزند هنوز باقی هستش. در این حالت اصطلاحا re-parenting به صورت خودکار انجام می گیرد. این کار توسط init صورت می گیره و به نوعی init قیم (شبه والد) فرایند میشه ولی همچنان فرایند فرزند یتیم باقی می مونه چون والد اصلیش از بین رفته (به دلیل crash و خاتمه ناگهانی و نه kill شدن فرایند والد)

اما یک فرایند زامبی فرایندی هستش که به اجری اون طور کامل خاتمه یافته اما هنوز یک مدخل یا ورودی در جدول فرایند های سیستم عامل دارد. این جدول فهرستی از فرایند ها رو داره. در اصل فرایند های زامبی فرایند های مرده یا dead processes هستن. (فیلم مردگان متحرک اگه دیده باشید زامبی ها قبلن مردن ولی فقط افکار گذشته اونها وجود داره D:).

اگه بخواهیم فرایند های زامبی رو پیدا کنیم دستور زیر رو اجرا می کنیم.

ps aux awk '{ print $8 " " $2 }' grep -w Z

وقتی فرایندی خاتمه پیدا کنه یک exit status code رو به والدش ارسال می کنه ولی به عنوان یک فرایند زامبی در جدول فرایند های سیستم عامل باقی می ماند. در خروجی دستور بالا فرایند های زامبی با Z مشخص می شوند. یعنی فرایند فرزند لازم است که مدخل خودش رو در جدول فرایند ها تا زمانی که والدش EXIT CODE فرزند رو بخواند باقی بمونه. (زیاد نمی دونم ولی والد نوع وضعیت خروجی فرزند رو باید بدونه). حالا وقتی والد کد وضعیت خروجی رو خواند حالا مدخل فرایند فرزند از جدول فرایند های سیستم عامل پاک خواهد شد.

اما چرا فرایند فرزند باید به صورت زامبی در جدول فریاند باقی بمونه تا والد exit status اونرو بفهمه؟ در یکی از منابع و نه البته معتبر اینطور گفته بود که "چون والد باید بفهمه که فرزندش برای اجرا شدن زمانبندی نشده باشه."

امیدوارم که کمک کرده باشم

محمد نصیری

خیلی جالب بود من تا حالا فکر می کردم Orphaned Process و Zombie Process ها یکی هستند که اینجوری نیست ، متشکرم

محمد نصیری

یه سئوالی برام پیش اومده ، خوب اگر یک سری از فرآیند ها بر اساس گذر زمان مرتب Orphaned بشن و خوب init مجددا بیاد و Parent بشه براشون اینها می تونن قدرت پردازشی CPU و حتی حافظه RAM سیستم رو بگیرند و به مرور باعث کندی سرویس دهی بشن ، البته این برداشت من هست ، اگر اینطور باشه ما باید این فرآیند های Orphaned رو هم شناسایی کنیم ، خوب گفتین که با دستور قبلی میشه فرآیند های Zombie رو دید ، آیا ما میتونیم فرایند های Orphaned رو هم شناسایی کنیم و Kill کنیم بدون اینکه سیستم طبیعتا Downtime داشته باشه یا خیر ؟ ممنون

امیر احمدی نامی

راستش رو بخواید نمی تونم دقیق به سوالتون در مورد قدرت پردازشی و کارایی پاسخ بدم چون تجربه کافی ندارم. اما وقتی فرایندی یتیم میشه که والدش از بین بره ولی خود فرایند در حالت اجرا باقی می منه. در این حالت init والد یا قیم فرایند فرزند میشه ولی فرایند فرزند بازم یتیم خواهد ماند. در حالت orphan نمی شه فرایند والد رو kill کرد چون والدش init شده ولی میشه با با دستور زیر

kill -9 PID_OF_ORPHANED_PROCESS

فرایند یتیم رو کشت. همچنین فکر می کنم فرایند یتیم پس از از بین رفتن والدش بازم همون شناسه اولیه خودش رو حفط می کنه.

اما برای پیدا کردن فرایند های یتیم این لینک رو بخونید.

اما در مورد فرایند های زامبی به علت اینکه خود فرایند فرزند خاتمه یافته یا به نوعی مرده، پس نمیشه اونرو KILL کرد. اما میشه والد اونرو kill کرد. این لینک رو مطالعه کنید متوجه می شید. تنها اینکه در لینک فوق PID یعنی Process ID و شناسه فرزند و PPID یعنی Parent Process ID و شناسه والد هست و عددی که زیر این ستون هست رو باید برای kill کنیم تا فرایند زامبی از بین بره.

FractalMan

pstree خیلی باحال بود ...

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره پاییزه می تونی امروز ارزونتر از فردا خرید کنی ....