درس آموزشی درس ۲ از ۵

مدیریت سرویس در لینوکس چیست؟ آموزش systemctl و عیب‌یابی systemd

سرور روشنه ولی برنامه کارت رو انجام نمی‌ده؟ با یک سرویس آزمایشی یاد بگیر systemctl، journalctl و systemd چطور بهت کمک می‌کنن علت واقعی مشکل رو پیدا کنی.

مقدماتی ۳۳ دقیقه مطالعه بروزرسانی ۲۲ مهر ۱۴۰۵
فهرست این درس

فرض کن صبح می‌ری سراغ یه سرور لینوکسی. اتصال SSH برقراره، سرور روشنه و اینترنت هم مشکلی نداره؛ ولی برنامه‌ای که باید هر چند دقیقه صف کارهای یه کارگاه رو بررسی کنه، از دیشب خبری ازش نیست. اولین واکنشت چیه؟ سریع restart می‌زنی؟ من می‌خوام توی این درس یه روش بهتر یاد بگیری: اول وضعیت سرویس رو بررسی کن، بعد سراغ راه‌حل برو. با همین نگاه، آموزش systemd رو از یه سری دستور حفظ‌کردنی به یه مهارت واقعی تبدیل می‌کنیم.

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

برای یاد گرفتن مدیریت سرویس در لینوکس، هم سراغ آموزش systemctl می‌ریم، هم لاگ‌ها رو با journalctl می‌خونیم. قرار نیست برای تمرین سرویس SSH یا دیتابیس واقعی رو دست‌کاری کنیم؛ یه سرویس آزمایشی در حساب کاربری خودت می‌سازیم. فقط حواست باشه بخش عملی سرویس به محیطی با systemd و مدیر سرویس کاربری فعال نیاز داره. روی بعضی کانتینرها یا نصب‌های WSL شاید این بخش اجرا نشه؛ برای اون حالت هم تمرین جدا داریم.

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

مدیریت سرویس در لینوکس یعنی چی؟

یه وب‌سرور رو تصور کن: قرار نیست هر بار که کاربر درخواست می‌فرسته، مدیر سرور دستی برنامه رو اجرا کنه. یا سرویس SSH باید برای اتصال‌های بعدی آماده باشه. وقتی درباره مدیریت سرویس‌های لینوکس حرف می‌زنیم، منظورمون همین چرخه‌ست؛ از شروع و توقف سرویس گرفته تا تنظیم فعال‌سازی، دیدن وضعیت و پیدا کردن علت شکست. البته همه سرویس‌ها قرار نیست همیشه در حال اجرا باشن.

حالا یه نکته ظریف: هر پردازشی که اجرا می‌کنی «سرویس» نیست. مثلاً اگه توی ترمینال python3 app.py بزنی، یه پردازش راه انداختی؛ تا وقتی مدیریتش رو به یه سرویس‌منیجر نسپری، نمی‌تونی ازش رفتار تعریف‌شده هنگام بوت، شکست یا بسته‌شدن نشست رو انتظار داشته باشی. تازه بعضی سرویس‌ها برای یه کار چندثانیه‌ای ساخته می‌شن و بعد از موفقیت تموم می‌شن. این موضوع موقع پیدا کردن علت خطا خیلی به کارت میاد.

پس موقع بررسی وضعیت سرویس در لینوکس، با دیدن inactive فوری نگو «خراب شده». اول نوع Unit و نتیجه آخرین اجرا رو بشناس. کمی جلوتر می‌بینی سرویسی با Type=oneshot ممکنه دقیقاً کارش رو انجام داده باشه و بعد دیگه در حال اجرا نباشه. تفاوت «اجرا نیست» و «ناموفق اجرا شده» رو از همین حالا برای خودت جدا کن.

systemd چیست و systemctl چه فرقی باهاش داره؟

توی آموزش systemd دو اسم مدام کنار هم می‌آن: systemd و systemctl. خود systemd مجموعه‌ای از اجزای مدیریت سیستم و سرویس‌هاست و روی خیلی از توزیع‌های امروزی نقش init رو هم داره. اما systemctl ابزاریه که از ترمینال باهاش به مدیر systemd دستور می‌دی یا ازش وضعیت می‌پرسی. خیلی ساده: یکی مدیریت می‌کنه، اون یکی واسطه دستورهای ماست. اگه این دو تا رو قاطی نکنی، ادامه آموزش systemctl هم خیلی روشن‌تر می‌شه.

یه نکته که موقع عیب‌یابی سرویس در لینوکس نجاتت می‌ده اینه که systemd لزوماً توی هر محیطی PID 1 نیست. روی نصب‌های معمول سرورهای Linux اغلب همین‌طوره، اما داخل کانتینر ممکنه یه برنامه دیگه پردازش شماره یک باشه. روی WSL هم فعال بودن systemd به تنظیمات بستگی داره. بنابراین وقتی systemctl به Bus وصل نمی‌شه، از همون اول به فایل سرویس گیر نده؛ اول وجود مدیر سرویس رو بررسی کن.

ps -p 1 -o pid=,comm=
command -v systemctl
systemctl --version | head -n 1

این سه فرمان رو بزن و خروجی‌شون رو کنار هم بذار. اولی می‌گه PID 1 چه برنامه‌ایه، دومی وجود ابزار systemctl رو بررسی می‌کنه و سومی نسخه اون رو نشون می‌ده. نصب بودن systemctl به معنی فعال بودن systemd نیست. برای ادامه این تمرین بهتره از یه ماشین مجازی Ubuntu یا Debian استفاده کنی که واقعاً با systemd بوت شده باشه.

سرویس، Unit و Daemon؛ سه اصطلاح شبیه ولی یکسان نیستن

قبل از ادامه مدیریت سرویس در لینوکس، سه اصطلاح رو جدا کنیم. «سرویس» معمولاً یه قابلیت مثل وب‌سرویس یا SSH رو توصیف می‌کنه. Daemon به پردازشی می‌گیم که معمولاً بدون تعامل مستقیم با کاربر کار می‌کنه. Unit هم اسم عمومی چیزیه که systemd مدیریتش می‌کنه؛ از Service گرفته تا Timer، Socket، Mount یا Target. پس هر Unit یه برنامه دائماً فعال نیست و این تفاوت موقع کار با systemd مهمه.

فایل Unit در اصل یه فایل متنیه که به systemd می‌گه با اون واحد چه رفتاری داشته باشه. مثلاً nginx.service می‌تونه تنظیمات اجرای وب‌سرور رو تعریف کنه و یه فایل مثل cleanup.timer زمان‌بندی یه کار رو مشخص کنه. توی این درس وارد همه انواع Unit نمی‌شیم؛ تمرکز آموزش ساخت سرویس در لینوکس روی فایل .service و رفتاریه که با دست خودمون آزمایش می‌کنیم.

نوع Unitکاربردنمونه نام
serviceاجرای یک برنامه یا کار پس‌زمینهnginx.service
socketتعریف سوکت و گاهی شروع سرویس هنگام نیازexample.socket
timerزمان‌بندی یک کارcleanup.timer
targetگروه‌بندی و هماهنگی واحدهاmulti-user.target
mountمدیریت یک نقطه Mountdata.mount

یه اشتباه رایج توی تنظیم وابستگی‌ها اینه که فکر کنی نوشتن نام سرویس دیگر یعنی اون سرویس حتماً آماده پاسخ‌دادنه. نه! Wants= و Requires= درباره وابستگی حرف می‌زنن، اما After= درباره ترتیب اجراست. هیچ‌کدوم به‌تنهایی تضمین نمی‌کنن برنامه وابسته واقعاً آماده ارائه سرویس شده. وقتی بعداً به بررسی علت خرابی سرویس می‌رسی، این تفاوت جلوی کلی تشخیص اشتباه رو می‌گیره.

پرونده آموزشی این درس : دستگاه پیش‌نمایش فیلم‌های قدیمی

بیا مدیریت سرویس‌های لینوکس رو با یه داستان مشخص جلو ببریم. فرض کن یه کارگاه فیلم‌های هشت‌میلی‌متری رو دیجیتال می‌کنه. فایل‌های مشتری‌ها وارد یه صف می‌شن و برنامه کوچیکی به اسم nb-preview-check باید تعداد کلیپ‌های صف رو بررسی کنه. این کارگاه و اطلاعاتش فرضی‌ان؛ این سناریو رو فقط برای آموزش ساخت سرویس systemd و پیدا کردن خطاها طراحی کردیم.

صبح مسئول کارگاه می‌بینه گزارش تازه‌ای ثبت نشده. یکی می‌گه سرویس اصلاً بالا نیومده، یکی فکر می‌کنه برنامه هنگ کرده، یکی هم اصرار داره سرور رو ری‌استارت کنیم. هیچ‌کدوم هنوز مدرک ندارن. ما برای بررسی وضعیت سرویس در لینوکس اول مطمئن می‌شیم Unit وجود داره، بعد سراغ وضعیت اجرا، لاگ و در نهایت خروجی واقعی برنامه می‌ریم. به همین ترتیبه که از حدس به تشخیص می‌رسیم.

چرا این همه مرحله؟ چون «گزارش نداریم» می‌تونه چند دلیل داشته باشه: Unit اصلاً شناخته نشده، برنامه اجرا شده ولی فایل ورودی نداره، خطا داده یا خروجی رو جای دیگه نوشته. هدف عیب‌یابی سرویس در لینوکس این نیست که اولین پیام خطا رو اسم مشکل بذاریم؛ باید ببینیم ریشه خطا کجاست. این روش برای سرویس آزمایشی و سرور واقعی یکسانه، فقط سطح ریسک فرق می‌کنه.

آموزش systemctl

قبل از دست زدن به سرویس، چهار سؤال بپرس

برای اینکه وسط آموزش systemctl سرگردون نشی، چهار سؤال ثابت داشته باش. یک: خود Unit وجود داره؟ دو: وضعیت فعلی و نتیجه آخرین اجرا چیه؟ سه: لاگ‌ها چه سرنخی می‌دن؟ چهار: خروجی واقعی برنامه همونیه که انتظار داشتیم؟ من اسم این روش رو می‌ذارم «چهار شاهد». هر فرمانی که بعداً می‌زنی باید برای جواب دادن به یکی از همین سؤال‌ها باشه.

مثلاً اگه فایل Unit هنوز ساخته نشده باشه، restart چه چیزی رو درست می‌کنه؟ اگه مسیر خروجی اشتباه باشه، ده بار ری‌استارت فقط همون اشتباه رو تکرار می‌کنه. یا وقتی یه مجوز دسترسی غلطه، باید مالکیت و دسترسی فایل رو بررسی کنی. توی عیب‌یابی سرویس‌های لینوکس، زیاد دستور زدن مزیت نیست؛ درست انتخاب کردن فرمان مهمه.

سؤالشاهد مناسبنتیجه‌ای که هنوز نمی‌تونیم بگیریم
Unit تعریف شده؟systemctl cat / list-unit-filesوجود Unit، تضمین اجرای سالم نیست
الان چه وضعیتی داره؟systemctl status / is-activeactive الزاماً به معنی درست کار کردن برنامه نیست
آخرین خطا چی بوده؟journalctl -uهر Warning الزاماً علت ریشه‌ای نیست
کار مورد انتظار انجام شده؟بررسی فایل یا خروجی برنامهموفقیت systemctl به‌تنهایی کافی نیست

آموزش systemctl برای مدیریت سرویس در لینوکس؛ از کجا شروع کنیم؟

خب، بریم سراغ آموزش systemctl و اول دستورهای فقط‌خواندنی رو ببینیم. با این ابزار می‌تونی Unitهای بارگذاری‌شده، فایل‌های سرویس و موارد شکست‌خورده رو فهرست کنی؛ لازم نیست از همون اول دست به start و stop بزنی. روی ماشینی که systemd فعاله، بخش زیادی از این اطلاعات بدون دسترسی root هم دیده می‌شه، هرچند بعضی جزئیات مجوز بیشتری می‌خوان.

systemctl list-units --type=service --all --no-pager
systemctl list-unit-files --type=service --no-pager
systemctl --failed --no-pager

خروجی list-units و list-unit-files رو یکی فرض نکن. اولی Unitهایی رو می‌بینه که مدیر systemd در حافظه داره؛ گزینه --all وضعیت Unitهای بارگذاری‌شده ولی غیرفعال رو هم نشون می‌ده. دومی درباره فایل‌های Unit و وضعیت فعال‌سازی اون‌هاست، حتی اگه سرویس الان اجرا نشه. این تفاوت جزو پایه‌های مدیریت سرویس در لینوکس و دلیل نابرابر بودن تعداد ردیف‌های دو خروجیه.

یه نکته هنگام کار با systemctl: اسم سرویس‌ها روی همه توزیع‌ها یکسان نیست. روی Ubuntu و Debian معمولاً ssh.service رو می‌بینی، ولی روی بعضی سیستم‌های خانواده Red Hat ممکنه sshd.service باشه. برای Apache هم apache2.service و httpd.service وجود دارن. قبل از کپی کردن فرمان، اسم Unit واقعی سیستم خودت رو پیدا کن؛ اسم اشتباه خودش می‌تونه آدم رو بی‌دلیل وارد عیب‌یابی کنه.

برای مدیریت سرویس در لینوکس، وضعیت رو چطور بخونیم؟

حالا نوبت مهم‌ترین فرمان برای بررسی وضعیت سرویس در لینوکسه: systemctl status. فرض کنیم روی Ubuntu سرویس SSH نصب شده. این فرمان معمولاً نام و مسیر Unit، وضعیت جاری، گاهی PID و چند خط آخر رخدادها رو نشون می‌ده. اگه روی سیستم تو SSH نصب نیست یا اسمش فرق می‌کنه، همین فرمان رو با یه Unit موجود امتحان کن؛ فقط برای شبیه شدن به مقاله چیزی نصب نکن.

systemctl status ssh.service --no-pager
systemctl is-active ssh.service
systemctl is-enabled ssh.service

این دو تا پرسش فرق دارن: «الان سرویس فعاله؟» و «برای فعال شدنش چه تنظیمی انجام شده؟». is-active به اولی جواب می‌ده و is-enabled به دومی. ممکنه سرویس در حال اجرا باشه ولی enabled نباشه، یا enabled باشه و همین حالا کار نکنه. وضعیت‌هایی مثل static، indirect و masked هم داریم. مدیریت سرویس در لینوکس یعنی این خروجی‌ها رو کنار هم تفسیر کنی، نه اینکه فقط دنبال کلمه سبز بگردی.

یه دام رایج اینه که active (exited) رو با خرابی اشتباه بگیری. بعضی سرویس‌ها بعد از انجام کار کوتاه، از نظر systemd هنوز فعال حساب می‌شن؛ در مقابل، یه سرویس active (running) ممکنه واقعاً به کاربر جواب نده. پس هنگام بررسی وضعیت سرویس‌های لینوکس، فقط وضعیت مدیریتی رو نبین؛ عملکرد برنامه، مثل پاسخ HTTP یا ساخته شدن فایل خروجی، رو هم جدا آزمایش کن.

فرق start و enable در مدیریت سرویس در لینوکس

حالا فرض کن سرویس رو start کردی، اما بعد از روشن شدن دوباره سیستم اجرا نشده. چرا؟ چون start درخواست اجرای همین لحظه‌ست، ولی enable معمولاً Unit رو به سازوکار فعال‌سازی تعریف‌شده وصل می‌کنه. به زبان ساده، enable به‌تنهایی سرویس رو همین حالا اجرا نمی‌کنه. این تفاوت یکی از اولین نکته‌های آموزش systemctl و پایه مدیریت سرویس در لینوکسه.

فرماناثر اصلینکته مهم
startدرخواست اجرای همین لحظهدر حالت معمول، تنظیم شروع خودکار را تغییر نمی‌دهد
enableفعال‌سازی طبق بخش Installبه‌تنهایی تضمین اجرای همین لحظه یا موفقیت برنامه نیست
enable –nowفعال‌سازی و درخواست شروعاگر اجرای برنامه خطا بده، همچنان باید عیب‌یابی کنی
disableحذف لینک‌های فعال‌سازی مرتبطالزاماً سرویس در حال اجرا را متوقف نمی‌کند
stopدرخواست توقف همین لحظهممکن است سرویس با محرک دیگری مجدداً فعال شود

توی این چند خط از اسم فرضی demo.service استفاده کردم تا فقط شکل فرمان‌ها رو ببینی؛ چنین سرویسی قرار نیست روی دستگاهت وجود داشته باشه. مخصوصاً برای تمرین سراغ SSH، پایگاه‌داده یا سرویس پرداخت واقعی نرو. چند بخش جلوتر آموزش ساخت سرویس در لینوکس رو روی یه User Service امن انجام می‌دیم که به sudo نیازی نداره.

sudo systemctl start demo.service
sudo systemctl enable demo.service
sudo systemctl enable --now demo.service

حواست باشه disabled یعنی لینک فعال‌سازی معمولِ Unit برداشته شده؛ نه اینکه اون سرویس هیچ‌وقت اجرا نمی‌شه. گاهی Timer یا Socket اون رو فعال می‌کنه و بعضی Unitها هم static هستن. موقع بررسی systemd، مهمه علاوه بر وضعیت enabled، مسیر واقعی فعال شدن سرویس رو هم بشناسی. همین شناخت موقع حل مشکل «چرا سرویس خودبه‌خود اجرا شد؟» به کارت میاد.

stop، restart و reload؛ کدوم رو چه زمانی بزنیم؟

وقتی تنظیمات یه برنامه رو تغییر می‌دی، باید restart بزنی یا reload؟ این سؤال توی مدیریت سرویس در لینوکس جواب یکسانی برای همه برنامه‌ها نداره. restart معمولاً اجرای قبلی رو متوقف و دوباره شروع می‌کنه؛ پس شاید وقفه ایجاد بشه. reload از برنامه می‌خواد تنظیماتش رو دوباره بخونه، البته فقط اگه خودش پشتیبانی کنه. قبل از انتخاب، مستندات همون سرویس رو ببین.

اسم سوم، daemon-reloadه. این یکی تنظیمات خود برنامه، مثل nginx.conf، رو بازخوانی نمی‌کنه؛ به مدیر systemd می‌گه فایل‌های Unit و ساختار وابستگی رو دوباره بخون. پس وقتی خود فایل سرویس systemd رو تغییر دادی، daemon-reload مناسبه، اما شاید برای اعمال تغییر در پردازش در حال اجرا هنوز به کار جداگانه‌ای نیاز باشه. این بخش از آموزش systemctl رو با restart و reload قاطی نکن.

# فقط نمونه دستوری؛ روی سرویس واقعی بدون برنامه توقف اجرا نکن
sudo systemctl restart demo.service
sudo systemctl reload demo.service
sudo systemctl daemon-reload

این تفاوت روی سرور واقعی شوخی‌بردار نیست. ری‌استارت عجولانه دیتابیس یا وب‌سرور می‌تونه ارتباط کاربران رو قطع کنه. وقتی درباره تشخیص خرابی سرویس حرف می‌زنیم، هدف فقط حذف پیام خطا نیست؛ می‌خوایم با کمترین اختلال علت مشکل رو پیدا کنیم، تغییر لازم رو انجام بدیم و نتیجه رو بسنجیم.

لاگ سرویس‌ها رو با journalctl چطور بخونیم؟

بریم سراغ آموزش journalctl؛ ابزاری که برای دیدن رخدادهای ثبت‌شده در Journal به کارت میاد. گزینه -u پیام‌های مربوط به یه Unit رو جدا می‌کنه، -b روی بوت مشخص تمرکز می‌کنه و --since محدوده زمانی می‌ده. برای مدیریت سرویس در لینوکس، یاد گرفتن خواندن لاگ از حفظ کردن ده‌ها گزینه مهم‌تره؛ چون بدون لاگ، درباره علت خرابی بیشتر حدس می‌زنی تا تشخیص.

journalctl -u ssh.service -b --no-pager -n 30
journalctl -u ssh.service --since "30 minutes ago" --no-pager
journalctl -b -p warning --no-pager -n 30

توی عیب‌یابی سرویس‌های لینوکس، آخرین خط Journal الزاماً دلیل اصلی خطا نیست. شاید فقط نوشته باشه برنامه بسته شد، درحالی‌که پیام مربوط به فایل گمشده چند خط بالاتره. بهتره زمان رخداد، کد خروج و پیام‌های قبل از شکست رو با هم بررسی کنی. اگه هم لاگ بوت قبلی رو ندیدی، نتیجه نگیر که بوت قبلی بی‌خطا بوده؛ ممکنه سیاست نگهداری لاگ فرق داشته باشه.

یه مقدار جلوتر برای تمرین رفع خطای سرویس failed، عمداً فایل ورودی برنامه رو نمی‌سازیم. اون‌وقت journalctl پیامی از خود برنامه نشون می‌ده که می‌گه queue.txt پیدا نشده. این پیام یه سرنخ واقعیه، نه حدس ما. مهمه یاد بگیری لاگ مدیر سرویس و خطای خود برنامه رو از هم جدا کنی.

فایل سرویس systemd چه ساختاری داره؟

قبل از ساخت سرویس، یه نگاه به ساختار فایل سرویس systemd بنداز. بخش [Unit] معمولاً معرفی و وابستگی‌ها رو مشخص می‌کنه، [Service] نحوه اجرای برنامه رو می‌گه و [Install] برای بعضی روش‌های فعال‌سازی استفاده می‌شه. توی آموزش systemd لازم نیست همه کلیدها رو از حفظ باشی؛ فعلاً بفهم هر بخش مسئول کدوم رفتارِ سرویسه.

[Unit]
Description=Example preview worker

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /some/real/path/check.py

[Install]
WantedBy=multi-user.target

این نمونه فقط برای آشنایی با قالب فایل Unitه؛ مسیر /some/real/path واقعی نیست و اجرای همین مثال شکست می‌خوره. به ExecStart دقت کن: مدیر سرویس نمی‌تونه خودش مسیر برنامه رو حدس بزنه. Type=oneshot هم یعنی انتظار داریم برنامه یک کار رو انجام بده و تموم بشه. کمی جلوتر توی آموزش ساخت سرویس در لینوکس مسیر واقعی رو خودمون مشخص می‌کنیم.

بسته به توزیع، فایل‌های Unit ممکنه زیر /usr/lib/systemd/system/ یا /lib/systemd/system/ باشن و تغییرات محلی معمولاً زیر /etc/systemd/system/ قرار می‌گیرن. فایل متعلق به پکیج رو مستقیم تغییر نده؛ ابزارهایی مثل systemctl edit برای تغییرات ماندگار وجود دارن. ما توی تمرین مدیریت سرویس‌های لینوکس حتی به اون سطح هم نمی‌ریم و یه Unit کاربری می‌سازیم.

آزمایش اصلی : یک سرویس کاربری بسازیم که عمداً خطا می‌ده

خب، وقت بخش عملی آموزش systemd رسیده. می‌خوایم یه برنامه بسازیم که اولین بار عمداً خطا بده، بعد با systemctl و journalctl دلیلش رو پیدا کنیم. برای اینکه سرویس سیستمی آسیب نبینه، از User Service استفاده می‌کنیم. بهتره روی ماشین مجازی Ubuntu یا Debian با systemd فعال باشی؛ توی محیط‌هایی که Bus کاربری ندارن، این قسمت ممکنه قابل اجرا نباشه.

اول پوشه پروژه رو داخل Home ایجاد کن. فقط قبلش مطمئن شو از قبل پوشه‌ای با همین نام و فایل‌های شخصی نداری؛ دستور بعد پوشه موجود رو پاک نمی‌کنه، ولی ممکنه فایل‌هایی که بعداً در اون می‌سازیم روی فایل هم‌نام قبلی نوشته بشن. این آموزش ساخت سرویس در لینوکس رو داخل nb-service-lab جلو می‌بریم و به سرویس‌های اصلی سیستم کاری نداریم.

mkdir -p "$HOME/nb-service-lab"
mkdir -p "$HOME/.config/systemd/user"
cd "$HOME/nb-service-lab"

برنامه‌مون باید فایل queue.txt رو بخونه و تعداد خط‌های غیرخالی رو گزارش بده. عمداً فعلاً این فایل رو نمی‌سازیم. پس اجرای اول باید با کد خروج غیرصفر شکست بخوره؛ بعد همین وضعیت رو برای آموزش عیب‌یابی سرویس در لینوکس بررسی می‌کنیم. با فرمان بعد فایل check.py رو بساز. اگه قبلاً این تمرین رو انجام دادی، قبل از اجرای دوباره فایل‌های موجود رو بررسی کن تا چیزی ناخواسته بازنویسی نشه.

cat > "$HOME/nb-service-lab/check.py" <<'PYLAB'
from pathlib import Path

home = Path.home()
queue = home / 'nb-service-lab' / 'queue.txt'
if not queue.is_file():
    raise SystemExit('ERROR: queue.txt is missing')

items = [line for line in queue.read_text(encoding='utf-8').splitlines() if line.strip()]
print(f'CHECK_OK: {len(items)} queued items', flush=True)
PYLAB

الان queue.txt رو نداریم، پس برنامه باید پیام مربوط به فایل گمشده رو بده. این شکست به معنی خراب بودن Python یا systemd نیست؛ خودمون ورودی لازم رو نساختیم. فرق بین خطای برنامه و خطای مدیر سرویس، یکی از پایه‌های رفع خطای سرویس failed هست. اول هم مستقیم با Python امتحان می‌کنیم تا این مرز رو روشن ببینی.

python3 "$HOME/nb-service-lab/check.py"
printf "exit_status=%s\n" "$?"

بعد از اجرای مستقیم برنامه، انتظار داریم پیام ERROR: queue.txt is missing و کد خروج غیرصفر ببینیم؛ برای همین کد، معمولاً مقدار ۱ ثبت می‌شه. حالا برای بررسی وضعیت سرویس در لینوکس یه فرضیه روشن داریم: برنامه بدون ورودی مورد نیازش کار نمی‌کنه. این خیلی بهتر از اینه که بدون دیدن نتیجه، systemd رو مقصر بدونیم.

فایل Unit رو بسازیم؛ بدون sudo و بدون سرویس سیستمی

حالا سراغ آموزش ساخت سرویس systemd در سطح کاربر بریم. فایل Unit رو در مسیر مخصوص User Service می‌ذاریم و از %h استفاده می‌کنیم تا systemd مسیر Home کاربر رو جایگزین کنه. نمونه ما فرض کرده Python در /usr/bin/python3 قرار داره. قبلش با command -v python3 مسیر واقعی رو ببین؛ اگه فرق داشت، همون خط ExecStart رو متناسب با دستگاهت تغییر بده.

cat > "$HOME/.config/systemd/user/nb-preview-check.service" <<'UNIT'
[Unit]
Description=Nabegheha preview queue check

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 %h/nb-service-lab/check.py

[Install]
WantedBy=default.target
UNIT

این فایل زیر ~/.config/systemd/user/ قرار می‌گیره و با systemctl --user مدیریتش می‌کنیم؛ پس اول این دستورها sudo نذار. توی مدیریت سرویس در لینوکس، User Service با سرویس سیستمی فرق داره: مدیر کاربر معمولاً هنگام ورود فعال می‌شه و بدون تنظیماتی مثل linger نباید فرض کنی سرویس از اولین لحظه بوت اجرا می‌شه. فعلاً هم قرار نیست سرویس نمونه رو خودکار فعال کنیم.

قبل از اجرا یه بررسی ساختاری انجام بده. systemd-analyze verify می‌تونه بعضی اشکال‌های فایل Unit رو پیدا کنه، ولی تضمین نمی‌کنه خود برنامه درست اجرا بشه. این تفاوت موقع بررسی فایل سرویس مهمه: معتبر بودن تعریف سرویس، با سالم بودن ورودی‌ها و خروجی‌های برنامه دو مسئله جداست.

systemd-analyze verify "$HOME/.config/systemd/user/nb-preview-check.service"

بعد از ساخت فایل سرویس systemd باید مدیر کاربری اون رو دوباره بخونه. برای همین daemon-reload می‌زنیم و بعد یک بار start می‌کنیم. اینجا عمداً enable نمی‌کنیم، چون نمی‌خوایم برنامه آزمایشی هنگام ورود کاربر خودکار اجرا بشه. هدف این تمرین اینه که اثر دقیق هر فرمان رو ببینی، نه اینکه چند دستور رو پشت سر هم حفظ کنی.

systemctl --user daemon-reload
systemctl --user start nb-preview-check.service
systemctl --user status nb-preview-check.service --no-pager

اولین start باید شکست بخوره؛ خودمون هنوز فایل ورودی رو نساختیم. اگه در خروجی status کلمه failed یا status=1/FAILURE رو دیدی، مرحله اول تمرین رفع خطای سرویس failed طبق انتظار پیش رفته. اما Failed to connect to bus داستان دیگه‌ایه: اون خطا ممکنه به مدیر سرویس کاربری مربوط باشه، نه فایل queue.txt. پیام‌ها رو با هم قاطی نکن.

حالا با journalctl علت خرابی رو پیدا کنیم

فرض کن کد Python رو ندیدی و فقط می‌دونی سرویس شروع نشده. برای عیب‌یابی سرویس در لینوکس اول status رو می‌خونیم، بعد سراغ آموزش journalctl در عمل می‌ریم. چون سرویس مال حساب کاربری خودمونه، دستور Journal رو با --user اجرا می‌کنیم. همین تفاوت کوچک جلوی بررسی لاگ اشتباه رو می‌گیره.

systemctl --user status nb-preview-check.service --no-pager
journalctl --user -u nb-preview-check.service -n 30 --no-pager

حالا پیام ERROR: queue.txt is missing رو می‌بینی؛ دقیقاً همون سرنخی که می‌خواستیم. این متن از برنامه اومده و systemd فقط نتیجه شکست اجرا رو ثبت کرده. برای رفع خطای سرویس failed باید بپرسیم فایل کجاست، باید چه کسی بسازتش و مسیرش درست تعریف شده یا نه. تا جواب این سؤال‌ها رو نداریم، ری‌استارت پی‌درپی راه‌حل نیست.

روی سرور واقعی هم نتیجه failed می‌تونه علت‌های مختلفی داشته باشه: پورت اشغال، تنظیمات نادرست، فایل گواهی ناخوانا یا دسترسی ناکافی. توی آموزش عیب‌یابی سرویس در لینوکس به‌جای اینکه همه رو با یه نسخه ثابت تعمیر کنیم، وضعیت Unit، کد خروج و لاگ برنامه رو کنار هم می‌ذاریم. تنها بعد از پیدا کردن علت، تغییر لازم رو انجام می‌دیم.

مشکل رو حل کنیم و موفقیت رو درست تشخیص بدیم

حالا فرض می‌کنیم بررسی کردیم و فایل صف واقعاً باید وجود داشته باشه. دو ورودی آزمایشی داخل queue.txt می‌نویسیم و سرویس رو دوباره start می‌کنیم. ولی این بار کار رو با دیدن موفق بودن فرمان تموم نکن: در مدیریت سرویس در لینوکس باید status، لاگ و خروجی مورد انتظار برنامه رو کنار هم بسنجی.

printf 'clip-a\nclip-b\n' > "$HOME/nb-service-lab/queue.txt"
systemctl --user start nb-preview-check.service
systemctl --user status nb-preview-check.service --no-pager
journalctl --user -u nb-preview-check.service -n 15 --no-pager

اگه همه‌چیز درست باشه، پیام CHECK_OK: 2 queued items رو می‌بینی. شاید status بعد از اجرای موفق inactive (dead) باشه؛ این الزاماً خرابی نیست، چون برنامه از نوع oneshot بوده و کارش تموم شده. پس موقع بررسی وضعیت سرویس‌های لینوکس حواست باشه وضعیت «الان در حال اجرا نیست» با «آخرین اجرا شکست خورده» فرق داره.

اگه وضعیت شکست قبلی هنوز توی خروجی‌ها باقی مونده، بعد از پیدا کردن و رفع علت می‌تونی systemctl --user reset-failed nb-preview-check.service رو بررسی کنی. این فرمان اطلاعات شکست ثبت‌شده رو پاک می‌کنه، اما فایل ورودی نمی‌سازه و مشکل برنامه رو خودش حل نمی‌کنه. توی رفع خطای سرویس failed همیشه ترتیب رو حفظ کن: اول تشخیص، بعد تعمیر و در صورت نیاز تمیزکردن وضعیت ثبت‌شده.

فرق active، inactive، failed و active (exited) چیه؟

چهار وضعیت مهم رو جدا کنیم: active (running) یعنی از نظر systemd پردازش در حال اجراست؛ inactive (dead) یعنی الان فعال نیست؛ failed یعنی شکستی ثبت شده؛ و active (exited) برای بعضی Unitها، مثلاً oneshot با RemainAfterExit=yes، طبیعی محسوب می‌شه. موقع خواندن وضعیت‌ها هیچ‌کدوم از این برچسب‌ها رو بدون دیدن نوع سرویس و نتیجه کارش تفسیر نکن.

وضعیتبرداشت اولیه درستکاری که باید بعدش بکنی
active (running)سرویس از نظر مدیر اجرا شدهسلامت خروجی یا پاسخ کاربردی را مستقل بررسی کن
inactive (dead)الان اجرا نیست یا کار کوتاه پایان یافتهنوع Unit و نتیجه اجرای اخیر را بررسی کن
failedیک شکست ثبت شدهjournal و کد خروج برنامه را بخوان
active (exited)Unit فعال است ولی پردازش قبلی تمام شدهType و RemainAfterExit را ببین
activatingشروع سرویس هنوز کامل نشدهزمان و علت انتظار را بررسی کن

یه مثال مهم برای بررسی وضعیت سرویس در لینوکس: وب‌سرور activeه، ولی سایت به‌خاطر قطع بودن دیتابیس خطای ۵۰۰ می‌ده. از نگاه مدیر سرویس، پردازش روشنه؛ از نگاه کاربر، سایت مشکل داره. پس برای مدیریت سرویس در لینوکس همیشه دوتا سؤال داشته باش: سرویس از نظر systemd چه وضعی داره و آیا واقعاً کار مورد انتظار رو انجام می‌ده؟

چرا سرویس enabled هست ولی بعد از ری‌استارت کار نمی‌کنه؟

وقتی سرویس enabledه اما بعد از راه‌اندازی سیستم کار نمی‌کنه، فقط دوباره enable نزن. شاید موقع شروع خطا داده، شاید فایل لازم آماده نبوده یا اصلاً با Timer و Socket فعال می‌شه. در User Service هم ممکنه مدیر کاربر هنوز شروع نشده باشه. عیب‌یابی سرویس در لینوکس از بررسی این مسیرهای فعال‌سازی شروع می‌شه، نه از تکرار دستورها.

توی مثال کارگاه فیلم تصور کن فایل صف روی دیسکی قرار گرفته که دیر Mount می‌شه. گذاشتن After=network.target یا After=remote-fs.target به‌تنهایی تضمین نمی‌کنه فایل موردنظر آماده‌ست. After= ترتیب شروع Unitها رو تعیین می‌کنه، نه سلامت سرویس خارجی یا موجود بودن داده رو. این یکی از ظرافت‌های کار با systemd برای عیب‌یابی سرویس‌های لینوکسه.

گاهی مشکل فقط یه مجوزه: سرویس با حساب کاربری معمولی اجرا می‌شه ولی می‌خواد توی پوشه‌ای بنویسه که فقط root بهش دسترسی داره. اینجا جواب «همه‌چیز رو chmod 777 کن» نیست. اول مالکیت، مجوزها و نیاز واقعی برنامه رو بررسی کن. اگر هنوز این مفاهیم برات مبهمه، درس مجوزهای Linux Essentials می‌تونه قبل از ادامه عیب‌یابی سرویس در لینوکس کمکت کنه.

چرا سرویس روی یک دستگاه اسم داره و روی دستگاه دیگه نه؟

اسم متفاوت Unit توی دو توزیع الزاماً نشونه مشکل نیست. بعضی سیستم‌ها ssh.service دارن و بعضی sshd.service؛ ممکنه برنامه‌ای هم اصلاً نصب نشده باشه. تازه همه توزیع‌های لینوکس از systemd استفاده نمی‌کنن. پس وقتی Unit not found می‌بینی، اول اسم واقعی Unit رو پیدا کن. این یکی از اولین قدم‌های آموزش systemctl روی توزیع‌های مختلفه.

systemctl list-unit-files --type=service --no-pager | grep -Ei "ssh|apache|httpd|nginx"
systemctl cat ssh.service --no-pager

اگه چیزی پیدا نشد، شاید سرویس موردنظر نصب نیست. اگه sshd.service وجود داره، همون رو با systemctl cat بررسی کن؛ این دستور فایل اصلی Unit و Drop-inهای مربوط رو نشون می‌ده. وقتی مدیریت سرویس‌های لینوکس رو یاد می‌گیری، باید بدونی مدیر سیستم دقیقاً کدوم تعریف رو می‌خونه، نه اینکه فقط اسم یه سرویس رو حدس بزنی.

تفاوت restart با تعمیر کردن؛ شش خطای رایج در مدیریت سرویس

توی عیب‌یابی سرویس در لینوکس شش اشتباه حسابی وقتت رو می‌گیرن: یکی گرفتن enabled و running، ری‌استارت کردن بدون خوندن لاگ، دست‌کاری مستقیم Unit متعلق به پکیج، جواب دادن به هر Permission denied با sudo، نتیجه گرفتن از یه Warning تنها و بی‌احتیاطی با disable یا mask. پنج مورد اول رو همین بالا دیدیم؛ ششمی رو جدا بررسی کنیم.

اشتباه ششم اینه که یه سرویس حساس رو بدون شناخت وابستگی‌هاش disable یا mask کنی. این دو فرمان یکسان نیستن و mask می‌تونه جلوی فعال شدن Unit از مسیرهای دیگه رو هم بگیره. وقتی مدیریت سرویس در لینوکس رو روی سرور واقعی انجام می‌دی، باید قبل از چنین تغییری اثرش روی بقیه سرویس‌ها و راه برگشت رو بدونی. توی آزمایش ما اصلاً نیازی به mask نیست.

یه عادت مهم دیگه هم اینه که با هر تغییر کوچیکی سراغ restart نری. بعضی برنامه‌ها reload دارن، بعضی ندارن و بعضی قبل از اعمال تغییر به تست تنظیمات نیاز دارن. کار با systemctl وقتی به درد می‌خوره که بفهمی کدوم فرمان کمترین اختلال رو ایجاد می‌کنه و بعد از اجرا چطور باید نتیجه رو بسنجی.

وقتی Unit رو تغییر می‌دیم، چطور مطمئن بشیم تنظیمات جدید دیده شده؟

فرض کن فایل سرویس systemd یا یکی از Drop-inها رو عوض کردی ولی برنامه هنوز مثل قبل کار می‌کنه. اول ببین فایل رو کجا ذخیره کردی و systemd کدوم نسخه رو می‌خونه. بعد daemon-reload رو بررسی کن. شاید لازم باشه خود پردازش هم دوباره اجرا بشه؛ اما این دو کار یکی نیستن. توی مدیریت سرویس‌های لینوکس، تشخیص همین تفاوت جلوی ری‌استارت‌های بی‌نتیجه رو می‌گیره.

systemctl --user daemon-reload
systemctl --user cat nb-preview-check.service --no-pager
systemctl --user show nb-preview-check.service -p FragmentPath -p ActiveState -p SubState

این فرمان‌ها رو فقط روی Unit آزمایشی خودمون اجرا کن. FragmentPath محل تعریف اصلی رو نشون می‌ده و ActiveState و SubState وضعیت رو با جزئیات می‌گن. اگه فایل Unit رو جابه‌جا کردی، مطمئن شو بعد از reload همون مسیری بارگذاری شده که انتظار داری. این بررسی کوچک بخشی از عیب‌یابی سرویس در لینوکس به‌شکل اصولیه.

آموزش آفلاین : حتی اگر systemd فعال نباشه، چی می‌تونیم تمرین کنیم؟

اگه الان فقط به یه کانتینر بدون systemd یا محیطی بدون مدیر سرویس کاربری دسترسی داری، هنوز می‌تونی بخش مهمی از تمرین رو انجام بدی. اجرای مستقیم برنامه Python نشون می‌ده نبودن فایل ورودی چه خطایی تولید می‌کنه و بعد از ساختنش چه تغییری رخ می‌ده. البته این تمرین جای آموزش systemd و اجرای واقعی systemctl --user و Journal رو نمی‌گیره؛ فقط منطق خطا و کد خروج رو روشن می‌کنه.

python3 "$HOME/nb-service-lab/check.py"
printf "exit_status=%s\n" "$?"
printf "clip-a\nclip-b\n" > "$HOME/nb-service-lab/queue.txt"
python3 "$HOME/nb-service-lab/check.py"
printf "exit_status=%s\n" "$?"

این قسمت یه تله داره: اگه قبلاً queue.txt رو ساخته باشی، اجرای اول دیگه نباید خطا بده. برای دیدن دوباره هر دو حالت، روی یه کپی جدا از پروژه کار کن. توی آموزش عیب‌یابی سرویس در لینوکس، «وضعیت اولیه داده‌ها» به‌اندازه خود دستور مهمه؛ قرار نیست برای شبیه شدن خروجی، فایل‌های شخصی رو پاک کنی.

اگه می‌خوای آزمایش رو از نو انجام بدی، یه کپی موقت از پروژه بگیر و فایل ورودی رو فقط توی همون کپی تغییر بده. این‌طوری بدون آسیب زدن به پروژه اصلی، رفتار خطا و موفقیت رو با هم مقایسه می‌کنی. یادت باشه اجرای مستقیم Python با اجرای زیر نظر systemd یکی نیست؛ مدیر سرویس امکاناتی مثل ثبت رخدادها، وابستگی‌ها و تنظیم فعال‌سازی رو هم اضافه می‌کنه.

منابع رسمی برای اینکه خودت هم جزئیات رو بررسی کنی

برای آموزش systemd بهتره هرجا رفتار یه فرمان مبهم شد، به مستندات نسخه همون سیستم رجوع کنی. راهنمای رسمی systemctl در Ubuntu، مستندات journalctl، راهنمای تغییر فایل‌های پکیج در Ubuntu Server و مستندات Red Hat می‌تونن کمک کنن. خروجی systemctl روی توزیع‌ها یا نسخه‌های مختلف لزوماً یکسان نیست.

این منابع رو برای وقتی گذاشتم که خواستی مدیریت سرویس‌های لینوکس رو عمیق‌تر یاد بگیری یا به تفاوت رفتار بین دو سیستم رسیدی. داستان کارگاه فیلم، فایل queue.txt و سرویس آزمایشی برای همین درس طراحی شدن. اگه خروجی دستگاهت با مثال فرق داشت، اول نسخه ابزارها و شرایط محیط رو بررسی کن، نه اینکه فکر کنی حتماً کار رو اشتباه رفتی.

تمرین دانشجو : چهار پرونده رو بدون حدس تحلیل کن

حالا نوبت خودته. چهار وضعیت می‌دم؛ برای هرکدوم اول بگو چه مدرکی لازم داری و آیا اصلاً restart منطقیه یا نه. این تمرین کمک می‌کنه آموزش systemctl و عیب‌یابی سرویس در لینوکس برات به مهارت تبدیل بشه، نه فهرستی از فرمان‌هایی که فقط حفظ کردی.

پرونده اول : سرویس اجرا شده ولی کاربر خطا می‌بینه

فرض کن systemctl status وب‌سرور رو active (running) نشون می‌ده، اما سایت خطای ۵۰۰ می‌ده. برای بررسی وضعیت سرویس در لینوکس فقط دیدن active کافی نیست. باید پاسخ واقعی سایت، لاگ برنامه و ارتباط با وابستگی‌هایی مثل دیتابیس رو هم آزمایش کنی. شاید مشکل اصلاً با ری‌استارت وب‌سرور حل نشه.

پرونده دوم : سرویس enabled هست ولی الان اجرا نمی‌شه

اینجا اول نوع Unit و نتیجه آخرین اجرای سرویس رو می‌پرسم. شاید یه کار oneshot بوده که تموم شده، شاید Timer یا Socket باید فعالش کنه یا شاید موقع شروع شکست خورده. توی مدیریت سرویس در لینوکس، enabled بودن سرنخه، نه حکم قطعی. وضعیت و لاگ باید با هم بررسی بشن.

پرونده سوم : برنامه بعد از تغییر Unit مثل قبل کار می‌کنه

اینجا اول مکان واقعی فایل Unit و Drop-inها رو پیدا می‌کنم، بعد می‌بینم daemon-reload اجرا شده یا نه. بسته به نوع تغییر، شاید خود سرویس هم نیاز به restart داشته باشه. این مثال نشون می‌ده کار با systemctl زمانی کامل می‌شه که بفهمی تغییر تعریف Unit با اجرای دوباره پردازش فرق داره.

پرونده چهارم : برنامه با کد صفر تموم شده ولی گزارش نساخته

این‌بار برنامه با کد صفر تموم شده، ولی گزارش مورد انتظار ساخته نشده. پس اجرای موفق از دید مدیر سرویس، الزاماً موفقیت کار از دید کاربر نیست. در عیب‌یابی سرویس در لینوکس باید وجود فایل خروجی، مسیرش و درست بودن داده‌ها رو هم بررسی کنی؛ شاید برنامه فقط پیام موفقیت چاپ کرده باشه.

چطور آزمایش رو تمیز جمع کنیم؟

آخر کار محیط آزمایش مدیریت سرویس در لینوکس رو هم مرتب کنیم. فقط Unit خودمون یعنی nb-preview-check.service رو حذف می‌کنیم. اگه خودت قبلاً enableش کرده بودی، اول disable رو انجام بده. بعد فایل Unit و در صورت تصمیم خودت پوشه پروژه رو پاک کن. مسیرها رو دقیق بخون و قبل از حذف مطمئن شو فایل شخصی داخل پروژه جا نذاشتی.

systemctl --user disable nb-preview-check.service
systemctl --user reset-failed nb-preview-check.service
rm -f "$HOME/.config/systemd/user/nb-preview-check.service"
systemctl --user daemon-reload
# بعد از بازبینی کامل محتوا و فقط اگر آزمایش را نمی‌خواهی:
# rm -r "$HOME/nb-service-lab"

اگه disable گفت سرویس فعال نبوده یا reset-failed چیزی برای پاک کردن نداشت، لزوماً مشکل تازه‌ای ایجاد نشده. فرمان حذف کل پوشه رو عمداً کامنت گذاشتیم. توی هر تمرین مدیریت سرویس در لینوکس، پاک‌سازی هم باید به‌اندازه نصب و اجرا حساب‌شده باشه؛ اول فایل‌های پوشه رو ببین، بعد تصمیم بگیر.

از نگاه آزمون LPIC-1، این درس رو کجا استفاده می‌کنی؟

حالا این آموزش systemd توی مسیر LPIC-1 چه جایگاهی داره؟ توی درس بوت لینوکس بیشتر درباره راه‌اندازی سیستم صحبت کردیم؛ اینجا درباره سرویس‌ها بعد از بوت و روش بررسی مشکلشون تمرین کردیم. اهداف رسمی LPIC-1 موضوعات مربوط به بوت و systemd رو هم پوشش می‌دن، اما قرار نیست ادعا کنیم این مقاله به‌تنهایی تمام جزئیات آزمون رو یاد می‌ده. تمرکز این درس روی یه مهارت عملی و تکرارپذیره.

اگه مسیرها، فایل‌ها و مجوزها هنوز برات روشن نیست، قبل از انجام تمرین به مسیر رایگان Linux Essentials سر بزن. اگه می‌خوای مدیریت سرویس در لینوکس و مباحث LPIC-1 رو منظم‌تر و با تمرین‌های بیشتر ادامه بدی، دوره کامل LPIC-1 نابغه‌ها هم در دسترسه. اما قبل از هر چیز سعی کن سرویس همین صفحه رو خودت بسازی و نتیجه هر مرحله رو بفهمی.

جمع‌بندی : قبل از restart، دنبال جواب بگرد

اگه قرار باشه از آموزش مدیریت سرویس در لینوکس فقط یه عادت برداری، این باشه: وضعیت فعلی، لاگ رخدادها و نتیجه واقعی کار رو با هم ببین. start با enable یکی نیست، restart با daemon-reload فرق داره و inactive همیشه شکست نیست. کسی که این تفاوت‌ها رو می‌فهمه، خیلی کمتر بی‌دلیل سراغ ری‌استارت می‌ره.

توی تمرین دیدیم چطور نبودن یه فایل باعث شکست سرویس شد، با آموزش journalctl سرنخ رو از لاگ پیدا کردیم و بعد از ساخت ورودی دوباره برنامه رو اجرا کردیم. در نهایت فهمیدیم یه سرویس oneshot می‌تونه موفق باشه و در عین حال بعد از انجام کار متوقف بشه. این همون روش عیب‌یابی سرویس‌های لینوکسه: اول شواهد، بعد علت، بعد کم‌خطرترین راه‌حل.

سؤالات متداول درباره systemd و systemctl

systemctl چیست و چه فرقی با systemd داره؟

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

فرق systemctl start با systemctl enable چیه؟

فرمان start درخواست می‌ده سرویس همین حالا اجرا بشه و enable معمولاً تنظیم فعال‌سازی رو برقرار می‌کنه. برای مدیریت سرویس در لینوکس بدون که هیچ‌کدوم تضمین نمی‌کنن خود برنامه سالم کار کنه. اگه واقعاً هر دو کار رو می‌خوای، enable --now رو هم بشناس.

چرا سرویس enabled هست ولی بعد از روشن شدن لینوکس اجرا نمی‌شه؟

اول وضعیت اجرا و لاگ رو بررسی کن. شاید سرویس موقع شروع خطا داده، فایل ورودی آماده نبوده یا با Timer و Socket فعال می‌شه. برای User Service هم وضعیت مدیر کاربر مهمه. عیب‌یابی سرویس در لینوکس یعنی علت اجرا نشدن رو پیدا کنی؛ enabled بودن به‌تنهایی نشون نمی‌ده برنامه موفق بوده.

آیا inactive بودن سرویس همیشه به معنی خرابی اونه؟

نه، همیشه این‌طور نیست. بعضی سرویس‌ها مثل Type=oneshot کار کوتاهی انجام می‌دن و بعد از پایان موفق، غیرفعال می‌شن. برای بررسی وضعیت سرویس در لینوکس باید نوع Unit، کد خروج، لاگ و نتیجه برنامه رو هم ببینی. فقط از روی inactive حکم نده.

فرق systemctl reload با daemon-reload چیه؟

فرمان reload از خود برنامه می‌خواد تنظیماتش رو دوباره بخونه، البته اگه این قابلیت رو داشته باشه. daemon-reload فایل‌های Unit رو برای مدیر systemd بازخوانی می‌کنه و خودش الزاماً پردازش رو restart نمی‌کنه. این تفاوت توی آموزش systemctl خیلی مهمه.

چطور خطای failed در یک سرویس لینوکس رو پیدا کنیم؟

برای رفع خطای سرویس failed اول systemctl status رو بخون، بعد با journalctl -u یا برای سرویس کاربری با journalctl --user -u سراغ لاگ برو. پیام‌های قبل از خطا و کد خروج رو کنار هم بررسی کن. توی آموزش journalctl هدف پیدا کردن علت خرابی و کم‌کردن ری‌استارت‌های بی‌فایده‌ست.

چرا systemctl داخل Docker یا WSL خطای Bus می‌ده؟

چون نصب بودن systemctl تضمین نمی‌کنه مدیر systemd اجرا شده باشه. داخل بعضی کانتینرها PID 1 چیز دیگه‌ایه و توی WSL هم فعال بودن systemd به تنظیمات بستگی داره. برای آموزش systemd با کمترین دردسر، ماشین مجازی لینوکسی با systemd فعال انتخاب کن.

برای یادگیری systemctl باید حتماً با sudo کار کنیم؟

نه. برای دیدن خیلی از وضعیت‌ها sudo لازم نیست. حتی می‌تونی آموزش ساخت سرویس در لینوکس رو با systemctl --user روی حساب خودت انجام بدی، به شرطی که مدیر کاربری فعال باشه. فقط تغییر سرویس‌های سیستمی معمولاً مجوز مدیریتی لازم داره.

می‌خواهی عمیق‌تر جلو بروی؟

این درس فقط یک بخش از مسیر کامل است

اگر می‌خواهی مباحث را به‌ترتیب، همراه تمرین و پروژه دنبال کنی، مسیر کامل دوره را ببین.

مشاهده دوره LPIC-1