ویرگول
ورودثبت نام
محمد مهدی شریفه
محمد مهدی شریفهعاشق ایران رئالیست دانشجوی لیسانس مهندسی کامپیوتر
محمد مهدی شریفه
محمد مهدی شریفه
خواندن ۳ دقیقه·۴ ماه پیش

چطور ساده ترین شل (shell) جهان رو نوشتم

سلام!
اگر تا حالا فکر کردید یک برنامه مثل ترمینال یا CMD چطور کار می‌کند، این مقاله را از دست ندهید. من یک شل ساده نوشتم که می‌خواهم به زبان خیلی ساده و خودمانی به شما بگویم این برنامه چطور کار می‌کند و چطور با چند خط کد، یک شل کوچک و کاربردی ساختم. این پروژه بیشتر برای یادگیری و تمرین خودم بود، ولی فکر کردم بد نیست تجربه‌ام را با شما هم به اشتراک بگذارم. اگر علاقه دارید می‌توانید کد را در گیت‌هاب من هم ببینید و از آن استفاده کنید.
در این مقاله قدم به قدم مراحل نوشتن شل را توضیح می‌دهم و نکاتی که در این مسیر یاد گرفتم را با شما درمیون می‌گذارم.

shell
shell

شل چیست ؟

شل در واقع برنامه‌ای است که ما با آن ارتباط برقرار می‌کنیم تا سیستم‌عامل دستورات ما را اجرا کند. وقتی در ترمینال دستور می‌نویسیم، مثلاً ls یا cd، این دستور به شل می‌رسد، شل آن را می‌فهمد، به سیستم‌عامل می‌گوید اجرا کند و بعد نتیجه را به ما نمایش می‌دهد.
شل مثل یک مترجم بین ما و سیستم‌عامل عمل می‌کند. علاوه بر این، شل می‌تواند برنامه‌های مختلف را با هم ترکیب کند، دستورات پیچیده‌تر بسازد و کارهای دیگری مثل مدیریت فایل‌ها و فرآیندها را آسان‌تر کند.
cmd در ویندوز و bash در لینوکس نمونه‌های معروف شل هستند.

چرا خودم شل نوشتم؟

شاید بپرسید، خب خیلی شل آماده هست، چرا من رفتم و یک شل ساده خودم نوشتم؟ راستش هدف اصلی من یادگیری بود. می‌خواستم بفهمم برنامه‌های خط فرمان چطور کار می‌کنند و چطور دستورات را اجرا می‌کنند.
علاوه بر این، ساختن یک شل ساده تمرین خوبی برای یادگیری مفاهیم مهمی مثل فرآیندها، فراخوانی‌های سیستمی و مدیریت ورودی و خروجی در سیستم‌عامل بود. ضمن اینکه این شل را با زبان C نوشتم که به سیستم نزدیک‌تر است و دسترسی کامل‌تری به منابع سیستم دارد.

شل ساده من: قابلیت‌ها و روش راه‌اندازی

حالا باید بدانیم اصلاً چه چیزی می‌خواهیم بسازیم و چه تفاوت‌هایی دارد؟ شل ما ساده‌ترین نوع شل است که برای سیستم‌عامل‌های یونیکسی (UNIX-like) مانند لینوکس و BSD نوشته شده است.
برای زبان برنامه‌نویسی، من از C استفاده کردم چون اولاً معروف‌ترین زبان برنامه‌نویسی سیستمی دنیاست و سازگاری خیلی خوبی با UNIX دارد. اکثر شل‌های دیگر هم با C نوشته شده‌اند.

انتخاب کامپایلر

زبان C برخلاف بسیاری از زبان‌های برنامه‌نویسی، چندین کامپایلر دارد؛ یعنی هر تیم یا گروهی ممکن است یک کامپایلر C اختصاصی ساخته باشد. تیم گنو (GNU) کامپایلر خودشان به نام gcc را ساخت که برای محیط‌های UNIX بهینه شده است.
ما هم از همان کامپایلر استفاده می‌کنیم.
برای نصب آن در اوبونتو می‌توانید از دستور زیر استفاده کنید:

sudo apt install gcc

شروع کد نویسی

خب، بریم کدنویسی را شروع کنیم. ابتدا باید هدر فایل‌های مورد نیاز را include کنیم و تابع main را بنویسیم.

تمپلیت برای شروع
تمپلیت برای شروع

سه include اول مربوط به کتابخانه‌های پایه زبان C هستند که توابعی مثل کار با رشته‌ها، ورودی/خروجی و توابع کمکی را فراهم می‌کنند. دو هدر بعدی unistd.h و sys/wait.h مربوط به سیستم‌کال‌های لینوکس برای ارتباط با سیستم‌عامل و مدیریت وقفه‌ها هستند که در ادامه بیشتر با آن‌ها آشنا می‌شویم.

ایجاد فرایند (process)

گفتیم که شل دستورات ما را اجرا می‌کند، اما چطور؟ شل نام هر برنامه‌ای که می‌نویسید را پیدا می‌کند و به عنوان یک فرآیند فرزند (subprocess) خودش اجرا می‌کند.
پس اولین قدم این است که یاد بگیریم چطور یک فرآیند فرزند ایجاد کنیم.

ایجاد فرایند فرزند
ایجاد فرایند فرزند

تابع fork برنامه را به دو شاخه پدر و فرزند تقسیم می‌کند. در شاخه فرزند عدد صفر برمی‌گرداند. شرط بررسی می‌کند اگر عدد صفر بود، با استفاده از تابع execvp برنامه‌ای که به شل داده شده را اجرا می‌کند. تابع wait در انتهای کد باعث می‌شود شاخه پدر منتظر پایان کار فرزند بماند.
برای اینکه بتوانیم نام برنامه را دریافت و پردازش کنیم باید یک حلقه بی‌نهایت بنویسیم که در نهایت کد برنامه چیزی شبیه به این میشه:

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

برای دیدن پروژه ی کامل هم میتونید به گیت هاب پروژه ی من به آدرس https://github.com/mohammadmehdisharife/bare-shell.git مراجعه کنید. ❤️

زبان برنامه‌نویسیشلگیت هاببرنامه نویسی
۴
۰
محمد مهدی شریفه
محمد مهدی شریفه
عاشق ایران رئالیست دانشجوی لیسانس مهندسی کامپیوتر
شاید از این پست‌ها خوشتان بیاید