لینوکس

مدیریت سرویس‌های Systemd با systemctl در لینوکس

مقدمه

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

در این راهنما، دستور systemctl را بحث می‌کنیم؛ که ابزار مدیریت مرکزی برای کنترل سیستم init است. پوشش می‌دهیم چگونه سرویس‌ها را مدیریت، وضعیت‌ها را چک، حالت‌های سیستم را تغییر و با فایل‌های پیکربندی کار کنید.

لطفاً توجه کنید که اگرچه systemd به سیستم init پیش‌فرض بسیاری از توزیع‌های لینوکس تبدیل شده، به‌طور جهانی بین همه توزیع‌ها پیاده‌سازی نشده است. هنگام مرور این آموزش، اگر ترمینال‌تان خطای bash: systemctl is not installed را خروجی داد، احتمالاً ماشین شما سیستم init متفاوتی نصب دارد.

با یک کلیک، دیتابیس دیپلوی کنید با دیتابیس‌های مدیریت‌شده پارمین کلود. بگذارید پارمین کلود روی مقیاس‌پذیری، نگهداری و ارتقاهای دیتابیس شما تمرکز کند.

نکات کلیدی

  • systemctl دستور اصلی‌ای است که برای مدیریت سرویس‌ها، یونیت‌ها و کل وضعیت سیستم روی سیستم‌های لینوکسیِ اجراکننده systemd استفاده خواهید کرد.
  • می‌توانید کل چرخه حیات سرویس را—شروع، توقف، ری‌استارت، Reload و کنترل رفتار بوت—با دستورات ساده systemctl مدیریت کنید.
  • دستوراتی مثل status، is-active، is-enabled و is-failed درک سریع اینکه سرویسی اجرا شده و سالم است یا نه را ساده می‌کنند.
  • systemctl به شما اجازه می‌دهد هم چیزی که الان فعال است و هم چیزی که روی سیستم موجود است را با فهرست کردن یونیت‌های بارگذاری‌شده و همه فایل‌های یونیت ببینید.
  • فایل‌های یونیت تعریف می‌کنند systemd چگونه منابع را مدیریت کند؛ و می‌توانید پیکربندی، ویژگی‌ها و وابستگی‌هایشان را مستقیماً از خط فرمان بازرسی کنید.
  • Mask کردن یونیت محافظتی قوی است که کاملاً جلوی شروع سرویس را تا وقتی صریحاً unmask شود می‌گیرد.
  • می‌توانید رفتار سرویس را با قطعه‌های Override یا ویرایش کامل فایل یونیت، به‌شکل امن سفارشی کنید؛ تا وقتی بعدش پیکربندی systemd را ریلود کنید.
  • Targetها مثل Runlevelها به‌عنوان حالت‌های سیستم عمل می‌کنند؛ که به شما اجازه کنترل رفتار بوت، ایزوله کردن محیط‌ها و انجام اقداماتی مثل بازیابی، خاموش کردن یا ریبوت را می‌دهند.

مدیریت سرویس‌ها

هدف بنیادی یک سیستم init، مقداردهی اولیه اجزایی است که باید بعد از بوت شدن کرنل لینوکس شروع شوند (سنتی به «اجزای Userland» معروف). سیستم init همچنین برای مدیریت سرویس‌ها و دیمن‌های سرور در هر نقطه‌ای حین اجرای سیستم استفاده می‌شود. با این در ذهن، با چند عملیات پایه مدیریت سرویس شروع می‌کنیم.

در systemd، هدف بیشتر اقدامات «یونیت‌ها» هستند؛ منابعی که systemd می‌داند چگونه مدیریت‌شان کند. یونیت‌ها بر اساس نوع منبعی که نمایندگی می‌کنند دسته‌بندی و با فایل‌هایی به نام فایل‌های یونیت تعریف می‌شوند. نوع هر یونیت را می‌توان از پسوند انتهای فایل استنباط کرد.

برای وظایف مدیریت سرویس، یونیت هدف، یونیت‌های سرویس خواهند بود؛ که فایل‌های یونیت‌شان پسوند .service دارند. اما برای بیشتر دستورات مدیریت سرویس، در واقع می‌توانید پسوند .service را حذف کنید؛ چون systemd به اندازه کافی هوشمند است که بفهمد احتمالاً می‌خواهید روی سرویسی عمل کنید وقتی از دستورات مدیریت سرویس استفاده می‌کنید.

شروع و توقف سرویس‌ها

برای شروع یک سرویس systemd—اجرای دستورالعمل‌های فایل یونیت سرویس—از دستور start استفاده کنید. اگر به‌عنوان کاربر غیر root اجرا می‌کنید، باید از sudo استفاده کنید؛ چون این روی وضعیت سیستم‌عامل اثر می‌گذارد:

sudo systemctl start application.service

همان‌طور که در بالا اشاره کردیم، systemd می‌داند برای دستورات مدیریت سرویس دنبال فایل‌های *.service بگردد؛ پس دستور را می‌توان به این شکل هم تایپ کرد:

sudo systemctl start application

هرچند ممکن است برای مدیریت عمومی از قالب بالا استفاده کنید، برای شفافیت، ما برای بقیه دستورات از پسوند .service استفاده می‌کنیم تا درباره هدفِ عمل‌کردن صریح باشیم.

برای متوقف کردن سرویسی که الان در حال اجراست، می‌توانید به‌جایش از دستور stop استفاده کنید:

sudo systemctl stop application.service

ری‌استارت و Reload

برای ری‌استارت سرویس در حال اجرا، می‌توانید از دستور restart استفاده کنید:

sudo systemctl restart application.service

اگر اپلیکیشن مربوطه قادر به Reload کردن فایل‌های پیکربندی‌اش (بدون ری‌استارت) باشد، می‌توانید دستور reload را برای شروع آن فرایند صادر کنید:

sudo systemctl reload application.service

اگر مطمئن نیستید سرویس قابلیت Reload پیکربندی‌اش را دارد، می‌توانید دستور reload-or-restart را صادر کنید. این در صورت موجود بودن، پیکربندی را در-جای خود Reload می‌کند. در غیر این صورت، سرویس را ری‌استارت می‌کند تا پیکربندی جدید برداشته شود:

sudo systemctl reload-or-restart application.service

فعال و غیرفعال کردن سرویس‌ها

دستورات بالا برای شروع یا توقف سرویس‌ها در طول نشست فعلی مفیدند. برای گفتن به systemd که سرویس‌ها را هنگام بوت خودکار شروع کند، باید فعال‌شان کنید.

برای شروع سرویس هنگام بوت، از دستور enable استفاده کنید:

sudo systemctl enable application.service

این، Symlinkهایی از نسخه سیستمی فایل سرویس (معمولاً در /lib/systemd/system یا /etc/systemd/system) به مکان روی دیسکی که systemd برای فایل‌های اتواستارت جستجو می‌کند (معمولاً /etc/systemd/system/some_target.target.wants) می‌سازد. بعداً در این راهندا مرور می‌کنیم که Target چیست).

برای غیرفعال کردن شروع خودکار سرویس، می‌توانید تایپ کنید:

sudo systemctl disable application.service

این Symlinkی را که نشان می‌داد سرویس باید خودکار شروع شود حذف می‌کند.

در نظر داشته باشید که فعال کردن سرویس، آن را در نشست فعلی شروع نمی‌کند. اگر مایلید سرویس را شروع و هم‌زمان هنگام بوت فعالش کنید، باید هر دو دستور start و enable را صادر کنید.

چک کردن وضعیت سرویس‌ها

برای چک کردن وضعیت سرویسی روی سیستم‌تان، می‌توانید از دستور status استفاده کنید:

systemctl status application.service

این وضعیت سرویس، سلسله‌مراتب cgroup و چند خط اول لاگ را به شما می‌دهد.

مثلاً هنگام چک کردن وضعیت سرور Nginx، ممکن است خروجی‌ای شبیه این ببینید:

Output
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
 Main PID: 495 (nginx)
   CGroup: /system.slice/nginx.service
           ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
           └─496 nginx: worker process
Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server...
Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server.

این نمای کلی خوبی از وضعیت فعلی اپلیکیشن به شما می‌دهد؛ و از هر مشکلی و هر اقدامی که ممکن است لازم باشد مطلعتان می‌کند.

روش‌هایی هم برای چک کردن وضعیت‌های خاص وجود دارد. مثلاً برای چک کردن اینکه آیا یونیتی الان فعال (در حال اجرا) است، می‌توانید از دستور is-active استفاده کنید:

systemctl is-active application.service

این وضعیت فعلی یونیت را برمی‌گرداند؛ که معمولاً active یا inactive است. کد خروج اگر فعال باشد ۰ خواهد بود؛ که نتیجه را برای پارس در شل اسکریپت‌ها ساده‌تر می‌کند.

برای دیدن اینکه آیا یونیت فعال (Enabled) شده، می‌توانید از دستور is-enabled استفاده کنید:

systemctl is-enabled application.service

این خروجی می‌دهد که سرویس enabled یا disabled است و باز هم بسته به جواب سوالِ دستور، کد خروج را روی ۰ یا ۱ تنظیم می‌کند.

چک سوم این است که آیا یونیت در وضعیت شکست‌خورده (Failed) است. این نشان می‌دهد مشکلی در شروع یونیت مربوطه بوده:

systemctl is-failed application.service

این اگر درست اجرا شود active و اگر خطایی رخ داده باشد failed برمی‌گرداند. اگر یونیت عمداً متوقف شده باشد، ممکن است unknown یا inactive برگرداند. وضعیت خروج ۰ نشان می‌دهد شکستی رخ داده و وضعیت خروج ۱ نشان می‌دهد هر وضعیت دیگری.

نمای کلی وضعیت سیستم

دستورات تا اینجا برای مدیریت سرویس‌های منفرد مفید بودند؛ اما برای کاوش وضعیت فعلی سیستم خیلی کمک‌کننده نیستند. تعدادی دستور systemctl این اطلاعات را فراهم می‌کنند.

فهرست کردن یونیت‌های فعلی

برای دیدن فهرستی از همه یونیت‌های فعلی که systemd می‌شناسد، می‌توانیم از دستور list-units استفاده کنیم:

systemctl list-units

این فهرستی از همه یونیت‌هایی که systemd الان روی سیستم فعال داشته را به شما نشان می‌دهد. خروجی چیزی شبیه این خواهد بود:

Output
UNIT                                      LOAD   ACTIVE SUB     DESCRIPTION
atd.service                               loaded active running ATD daemon
avahi-daemon.service                      loaded active running Avahi mDNS/DNS-SD Stack
dbus.service                              loaded active running D-Bus System Message Bus
dcron.service                             loaded active running Periodic Command Scheduler
dkms.service                              loaded active exited  Dynamic Kernel Modules System
getty@tty1.service                        loaded active running Getty on tty1
. . .

خروجی ستون‌های زیر را دارد:

  • UNIT: نام یونیت systemd
  • LOAD: اینکه آیا پیکربندی یونیت توسط systemd پارس شده یا نه. پیکربندی یونیت‌های loaded در حافظه نگه داشته می‌شود.
  • ACTIVE: وضعیت خلاصه درباره فعال بودن یونیت. این معمولاً روشی نسبتاً پایه برای فهمیدن اینکه یونیت با موفقیت شروع شده یا نه است.
  • SUB: این وضعیت سطح-پایین‌تری است که اطلاعات تفصیلی‌تری درباره یونیت نشان می‌دهد. این اغلب بسته به نوع یونیت، وضعیت و روش واقعی اجرای یونیت متفاوت است.
  • DESCRIPTION: توضیح متنی کوتاهی از اینکه یونیت چیست/چه می‌کند.

چون دستور list-units به‌طور پیش‌فرض فقط یونیت‌های فعال را نشان می‌دهد، همه ورودی‌های بالا در ستون LOAD مقدار loaded و در ستون ACTIVE مقدار active نشان می‌دهند. این نمایش در واقع رفتار پیش‌فرض systemctl هنگام فراخوانی بدون دستورات اضافی است؛ پس اگر systemctl را بدون آرگومان صدا بزنید همین را می‌بینید:

systemctl

می‌توانیم با افزودن فلگ‌های اضافی به systemctl بگوییم اطلاعات متفاوتی خروجی بدهد. مثلاً برای دیدن همه یونیت‌هایی که systemd بارگذاری کرده (یا تلاش به بارگذاری کرده)—فارغ از فعال بودن فعلی‌شان—می‌توانید از فلگ --all مثل این استفاده کنید:

systemctl list-units --all

این هر یونیتی را که systemd بارگذاری یا تلاش به بارگذاری کرده—فارغ از وضعیت فعلی‌اش روی سیستم—نشان می‌دهد. برخی یونیت‌ها بعد از اجرا غیرفعال می‌شوند و برخی یونیت‌هایی که systemd تلاش به بارگذاری‌شان کرد ممکن است روی دیسک پیدا نشده باشند.

می‌توانید از فلگ‌های دیگر برای فیلتر این نتایج استفاده کنید. مثلاً می‌توانیم از فلگ --state= برای نشان دادن وضعیت‌های LOAD، ACTIVE یا SUB که مایل به دیدنشان هستیم استفاده کنیم. باید فلگ --all را نگه دارید تا systemctl اجازه نمایش یونیت‌های غیرفعال را بدهد:

systemctl list-units --all --state=inactive

فیلتر رایج دیگر، فیلتر --type= است. می‌توانیم به systemctl بگوییم فقط یونیت‌های نوع موردعلاقه‌مان را نمایش دهد. مثلاً برای دیدن فقط یونیت‌های سرویس فعال، می‌توانیم استفاده کنیم:

systemctl list-units --type=service

فهرست کردن همه فایل‌های یونیت

دستور list-units فقط یونیت‌هایی را نمایش می‌دهد که systemd تلاش به پارس و بارگذاری‌شان در حافظه کرده. چون systemd فقط یونیت‌هایی را می‌خواند که فکر می‌کند لازم دارد، این لزوماً همه یونیت‌های موجود روی سیستم را شامل نمی‌شود. برای دیدن هر فایل یونیت موجودِ داخل مسیرهای systemd—شامل آن‌هایی که systemd تلاش به بارگذاری‌شان نکرده—می‌توانید به‌جایش از دستور list-unit-files استفاده کنید:

systemctl list-unit-files

یونیت‌ها نمایشی از منابعی هستند که systemd می‌شناسد. چون systemd در این دید لزوماً همه تعاریف یونیت را نخوانده، فقط اطلاعات خودِ فایل‌ها را ارائه می‌دهد. خروجی دو ستون دارد: فایل یونیت و وضعیت.

Output
UNIT FILE                                  STATE
proc-sys-fs-binfmt_misc.automount          static
dev-hugepages.mount                        static
dev-mqueue.mount                           static
proc-fs-nfsd.mount                         static
proc-sys-fs-binfmt_misc.mount              static
sys-fs-fuse-connections.mount              static
sys-kernel-config.mount                    static
sys-kernel-debug.mount                     static
tmp.mount                                  static
var-lib-nfs-rpc_pipefs.mount               static
org.cups.cupsd.path                        enabled
. . .

وضعیت معمولاً enabled، disabled، static یا masked خواهد بود. در این زمینه، static یعنی فایل یونیت بخش Install ندارد؛ که برای فعال کردن یونیت استفاده می‌شود. به این ترتیب، این یونیت‌ها نمی‌توانند فعال شوند. معمولاً، این یعنی یونیت اقدامی یک‌باره انجام می‌دهد یا فقط به‌عنوان وابستگی یونیت دیگری استفاده می‌شود و نباید خودش اجرا شود.

به‌زودی مرور می‌کنیم که masked یعنی چه.

مدیریت یونیت‌ها

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

نمایش یک فایل یونیت

برای نمایش فایل یونیتی که systemd در سیستمش بارگذاری کرده، می‌توانید از دستور cat استفاده کنید (این در systemd نسخه ۲۰۹ اضافه شد). مثلاً برای دیدن فایل یونیتِ دیمن زمان‌بندی atd، می‌توانستیم تایپ کنیم:

systemctl cat atd.service
Output
[Unit]
Description=ATD daemon

[Service]
Type=forking
ExecStart=/usr/bin/atd

[Install]
WantedBy=multi-user.target

خروجی فایل یونیتِ شناخته‌شده توسط پروسه systemd در حال اجرای فعلی است. این می‌تواند مهم باشد اگر اخیراً فایل‌های یونیت را تغییر داده‌اید یا اگر در حال Override کردن برخی گزینه‌ها در قطعه فایل یونیت هستید (بعداً این را پوشش می‌دهیم).

نمایش وابستگی‌ها

برای دیدن درخت وابستگی یک یونیت، می‌توانید از دستور list-dependencies استفاده کنید:

systemctl list-dependencies sshd.service

این سلسله‌مراتبی را نمایش می‌دهد که وابستگی‌هایی که برای شروع یونیت مربوطه باید مدیریت شوند را نگاشت می‌کند. وابستگی‌ها در این زمینه شامل آن یونیت‌هایی هستند که توسط یونیت‌های بالای خودشان Required یا Wanted شده‌اند.

Output
sshd.service
├─system.slice
└─basic.target
  ├─microcode.service
  ├─rhel-autorelabel-mark.service
  ├─rhel-autorelabel.service
  ├─rhel-configure.service
  ├─rhel-dmesg.service
  ├─rhel-loadmodules.service
  ├─paths.target
  ├─slices.target
. . .

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

وابستگی‌های بازگشتی فقط برای یونیت‌های .target—که حالت‌های سیستم را نشان می‌دهند—نمایش داده می‌شوند. برای فهرست بازگشتی همه وابستگی‌ها، فلگ --all را بگنجانید.

برای نمایش وابستگی‌های معکوس (یونیت‌هایی که به یونیت مشخص‌شده وابسته‌اند)، می‌توانید فلگ --reverse را به دستور اضافه کنید. فلگ‌های مفید دیگر --before و --after هستند؛ که می‌توانند برای نمایش یونیت‌هایی که به شروع‌شدن یونیت مشخص‌شده قبل یا بعد از خودشان وابسته‌اند استفاده شوند.

چک کردن ویژگی‌های یونیت

برای دیدن ویژگی‌های سطح-پایین یک یونیت، می‌توانید از دستور show استفاده کنید. این فهرستی از ویژگی‌های تنظیم‌شده برای یونیت مشخص‌شده را با قالب key=value نمایش می‌دهد:

systemctl show sshd.service
Output
Id=sshd.service
Names=sshd.service
Requires=basic.target
Wants=system.slice
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=shutdown.target multi-user.target
After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
Description=OpenSSH server daemon
. . .

اگر می‌خواهید یک ویژگی منفرد را نمایش دهید، می‌توانید فلگ -p را همراه نام ویژگی پاس کنید. مثلاً برای دیدن تضادهایی (Conflicts) که یونیت sshd.service دارد، می‌توانید تایپ کنید:

systemctl show sshd.service -p Conflicts
Output
Conflicts=shutdown.target

Mask و Unmask کردن یونیت‌ها

در بخش مدیریت سرویس دیدیم چطور سرویسی را متوقف یا غیرفعال کنیم؛ اما systemd همچنین توانایی علامت‌گذاری یونیتی به‌عنوان کاملاً غیرقابل-شروع—خودکار یا دستی—را با لینک کردن به /dev/null دارد. این Mask کردن یونیت نامیده می‌شود و با دستور mask ممکن است:

sudo systemctl mask nginx.service

این جلوی شروع شدن سرویس Nginx را—خودکار یا دستی—تا وقتی Mask شده می‌گیرد.

اگر list-unit-files را چک کنید، خواهید دید سرویس الان به‌عنوان masked فهرست شده:

systemctl list-unit-files
Output
. . .
kmod-static-nodes.service              static
ldconfig.service                       static
mandb.service                          static
messagebus.service                     static
nginx.service                          masked
quotaon.service                        static
rc-local.service                       static
rdisc.service                          disabled
rescue.service                         static
. . .

اگر سعی کنید سرویس را شروع کنید، پیغامی شبیه این می‌بینید:

sudo systemctl start nginx.service
Output
Failed to start nginx.service: Unit nginx.service is masked.

برای Unmask کردن یونیت و در دسترس قرار دادنش برای استفاده مجدد، از دستور unmask استفاده کنید:

sudo systemctl unmask nginx.service

این یونیت را به وضعیت قبلی‌اش برمی‌گرداند؛ و اجازه می‌دهد شروع یا فعال شود.

ویرایش فایل‌های یونیت

در حالی که قالب خاص فایل‌های یونیت خارج از محدوده این آموزش است، اگر لازم باشد تنظیماتی بدهید، systemctl سازوکارهای داخلی برای ویرایش و تغییر فایل‌های یونیت فراهم می‌کند. این قابلیت در systemd نسخه ۲۱۸ اضافه شد.

دستور edit به‌طور پیش‌فرض، قطعه فایل یونیتی برای یونیت مربوطه باز می‌کند:

sudo systemctl edit nginx.service

این فایل خالی‌ای خواهد بود که می‌توان برای Override یا افزودن دایرکتیو به تعریف یونیت استفاده شود. دایرکتوری‌ای درون /etc/systemd/system ساخته می‌شود که نام یونیت را با .d الصاق‌شده دارد. مثلاً برای nginx.service، دایرکتوری‌ای به نام nginx.service.d ساخته خواهد شد.

درون این دایرکتوری، قطعه‌ای به نام override.conf ساخته می‌شود. وقتی یونیت بارگذاری شود، systemd در حافظه، قطعه Override را با فایل کامل یونیت ادغام می‌کند. دایرکتیوهای قطعه بر آن‌هایی که در فایل یونیت اصلی هستند اولویت خواهند داشت.

اگر مایلید به‌جای ساخت قطعه، فایل کامل یونیت را ویرایش کنید، می‌توانید فلگ --full را پاس کنید:

sudo systemctl edit --full nginx.service

این فایل یونیت فعلی را در ویرایشگر بارگذاری می‌کند؛ جایی که قابل تغییر است. وقتی ویرایشگر خارج شود، فایل تغییرکرده به /etc/systemd/system نوشته خواهد شد؛ که بر تعریف یونیت سیستم (معمولاً در /lib/systemd/system یا /usr/lib/systemd/system) اولویت دارد.

برای حذف هر افزودنی که کرده‌اید، یا دایرکتوری پیکربندی .d یونیت یا فایل سرویس تغییرکرده را از /etc/systemd/system حذف کنید. مثلاً برای حذف یک قطعه، می‌توانستیم تایپ کنیم:

sudo rm -r /etc/systemd/system/nginx.service.d

برای حذف فایل یونیت کاملِ تغییرکرده، تایپ می‌کردیم:

sudo rm /etc/systemd/system/nginx.service

بعد از حذف فایل یا دایرکتوری، باید پروسه systemd را ریلود کنید تا دیگر تلاش به ارجاع این فایل‌ها نکند و به استفاده از نسخه‌های سیستم برگردد. این کار را با تایپ این می‌توانید انجام دهید:

sudo systemctl daemon-reload

تنظیم وضعیت سیستم (Runlevel) با Targetها

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

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

مثلاً، swap.targetای وجود دارد که طراحی شده نشان دهد Swap برای استفاده آماده است. یونیت‌هایی که بخشی از این فرایند هستند می‌توانند با نشان دادن در پیکربندی‌شان که توسط swap.target مورد Wanted یا Required هستند، با این Target هم‌گام شوند. یونیت‌هایی که نیاز به در دسترس بودن Swap دارند می‌توانند این شرط را با مشخصه‌های Wants=، Requires= و After= برای نشان دادن ماهیت رابطه‌شان مشخص کنند.

گرفتن و تنظیم Target پیش‌فرض

پروسه systemd یک Target پیش‌فرض دارد که هنگام بوت سیستم از آن استفاده می‌کند. برآوردن آبشاری وابستگی‌ها از آن Target منفرد، سیستم را به وضعیت مطلوب می‌آورد. برای پیدا کردن Target پیش‌فرض سیستم‌تان، تایپ کنید:

systemctl get-default
Output
multi-user.target

اگر مایلید Target پیش‌فرض متفاوتی تنظیم کنید، می‌توانید از set-default استفاده کنید. مثلاً اگر دسکتاپ گرافیکی نصب دارید و مایلید سیستم به‌طور پیش‌فرض به آن بوت شود، می‌توانید Target پیش‌فرضتان را متناسب تغییر دهید:

sudo systemctl set-default graphical.target

فهرست کردن Targetهای موجود

می‌توانید فهرستی از Targetهای موجود روی سیستم‌تان را با تایپ این بگیرید:

systemctl list-unit-files --type=target

برخلاف Runlevelها، چندین Target می‌توانند هم‌زمان فعال باشند. Target فعال نشان می‌دهد systemd تلاش کرده همه یونیت‌های مرتبط با Target را شروع کند و تلاش به پایین‌کشیدن دوباره‌شان نکرده. برای دیدن همه Targetهای فعال، تایپ کنید:

systemctl list-units --type=target

ایزوله کردن Targetها

امکان شروع همه یونیت‌های مرتبط با یک Target و متوقف کردن همه یونیت‌هایی که بخشی از درخت وابستگی نیستند وجود دارد. دستوری که برای این کار لازم داریم به‌درستی isolate نامیده می‌شود. این شبیه تغییر Runlevel در سیستم‌های init دیگر است.

مثلاً اگر در محیط گرافیکی با graphical.target فعال کار می‌کنید، می‌توانید سیستم گرافیکی را خاموش و سیستم را در وضعیت خط فرمان چندکاربره با ایزوله کردن multi-user.target قرار دهید. چون graphical.target به multi-user.target وابسته است اما برعکس نیست، همه یونیت‌های گرافیکی متوقف خواهند شد.

ممکن است مایل باشید قبل از انجام این فرایند، نگاهی به وابستگی‌های Targetی که ایزوله می‌کنید بیندازید تا مطمئن شوید سرویس‌های حیاتی را متوقف نمی‌کنید:

systemctl list-dependencies multi-user.target

وقتی از یونیت‌هایی که زنده نگه داشته می‌شوند راضی بودید، می‌توانید Target را با تایپ این ایزوله کنید:

sudo systemctl isolate multi-user.target

استفاده از میان‌برها برای رویدادهای مهم

Targetهایی برای رویدادهای مهم مثل خاموش کردن یا ریبوت تعریف شده‌اند. اما systemctl چند میان‌بر هم دارد که کمی قابلیت اضافی فراهم می‌کنند.

مثلاً برای قرار دادن سیستم در حالت بازیابی (تک-کاربره)، می‌توانید به‌جای isolate rescue.target از دستور rescue استفاده کنید:

sudo systemctl rescue

این قابلیت اضافیِ اطلاع‌رسانی همه کاربران واردشده درباره رویداد را فراهم می‌کند.

برای متوقف کردن سیستم (Halt)، می‌توانید از دستور halt استفاده کنید:

sudo systemctl halt

برای شروع خاموشی کامل (Poweroff)، می‌توانید از دستور poweroff استفاده کنید:

sudo systemctl poweroff

ری‌استارت را می‌توان با دستور reboot شروع کرد:

sudo systemctl reboot

این‌ها همه به کاربران واردشده اطلاع می‌دهند که رویداد در حال وقوع است؛ چیزی که فقط اجرا یا ایزوله کردن Target انجامش نمی‌دهد. توجه کنید که بیشتر ماشین‌ها دستورات کوتاه‌تر و متعارف‌تر این عملیات‌ها را لینک می‌کنند تا با systemd درست کار کنند.

مثلاً برای ریبوت سیستم، معمولاً می‌توانید تایپ کنید:

sudo reboot

فعال/غیرفعال کردن سرویس‌ها هنگام بوت

برای فعال کردن سرویسی که هنگام بوت خودکار شروع شود، از دستور enable همراه نام سرویس استفاده کنید. مثلاً برای فعال کردن سرویس httpd برای شروع هنگام بوت:

sudo systemctl enable httpd

برعکس، برای غیرفعال کردن شروع خودکار سرویس، از دستور disable همراه نام سرویس استفاده کنید. مثلاً برای غیرفعال کردن سرویس httpd از شروع هنگام بوت:

sudo systemctl disable httpd

چک کردن و تفسیر وضعیت سرویس

برای چک کردن وضعیت سرویسی، از دستور status همراه نام سرویس استفاده کنید. مثلاً برای چک کردن وضعیت سرویس httpd:

sudo systemctl status httpd

این دستور وضعیت فعلی سرویس—including اینکه اجرا می‌شود یا نه و هر پیام خطایی اگر اجرا نمی‌شود—را نمایش می‌دهد. اینجا خروجی نمونه‌ای برای کمک به تفسیر وضعیت سرویس هست:

httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-09-15 14:30:42 IST; 1min 23s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 12345 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=0/SUCCESS)
 Main PID: 12346 (httpd)
   Status: "Running, listening on ports 80 and 443."
   CGroup: /system.slice/httpd.service
           ├─12346 /usr/sbin/httpd -DFOREGROUND
           ├─12347 /usr/sbin/httpd -DFOREGROUND
           ├─12348 /usr/sbin/httpd -DFOREGROUND
           ├─12349 /usr/sbin/httpd -DFOREGROUND
           ├─12350 /usr/sbin/httpd -DFOREGROUND
           └─12351 /usr/sbin/httpd -DFOREGROUND

Sep 15 14:30:42 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
Sep 15 14:30:42 localhost.localdomain httpd[12345]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain. Set the 'ServerName' directive globally to suppress this message
Sep 15 14:30:42 localhost.localdomain systemd[1]: Started The Apache HTTP Server.

در این خروجی نمونه، سرویس active (running) است؛ یعنی الان در حال اجراست. خط Loaded مکان فایل سرویس و وضعیت فعلی‌اش را نشان می‌دهد. خط Active زمان شروع و مدت سرویس را فراهم می‌کند. خطوط Process دستور استفاده‌شده برای شروع سرویس و وضعیت خروجش را نمایش می‌دهند. خط Main PID شناسه پروسه (PID) پروسه اصلی سرویس را نشان می‌دهد. خط Status توضیح کوتاهی از وضعیت فعلی سرویس فراهم می‌کند. بخش CGroup پروسه‌های مرتبط با سرویس را فهرست می‌کند. پیام‌های لاگ در انتها اطلاعات اضافی درباره فرایند شروع سرویس فراهم می‌کنند.

Reload کردن پیکربندی بدون ری‌استارت کامل

برای Reload کردن پیکربندی سرویسی بدون ری‌استارت، از دستور reload همراه نام سرویس استفاده کنید. مثلاً برای Reload کردن پیکربندی سرویس httpd:

sudo systemctl reload httpd

این دستور به‌ویژه مفید است وقتی تغییراتی در فایل‌های پیکربندی سرویس داده‌اید و می‌خواهید آن تغییرات را بدون مختل کردن سرویس اعمال کنید.

نکته: همه سرویس‌ها Reload را پشتیبانی نمی‌کنند؛ اگر پشتیبانی نشود، دستور شکست می‌خورد مگر اینکه از reload-or-restart استفاده شود.

خطاهای رایج و دیباگ

خطاهای Failed to start unit یا Unit not found

هنگام مواجهه با خطاهای Failed to start unit یا Unit not found، ضروری است وجود و صحت فایل سرویس را تأیید کنید. مطمئن شوید فایل سرویس در دایرکتوری درست—مثل /etc/systemd/system/ یا /lib/systemd/system/—قرار دارد و نام فایل و پسوند درستی دارد (مثلاً httpd.service). علاوه بر این، فایل سرویس را برای خطاهای سینتکس یا وابستگی‌های نادرستی که ممکن است جلوی شروع سرویس را بگیرند چک کنید.

هنگام افزودن فایل‌های پیکربندی برای سرویسی، مطمئن شوید در دایرکتوری درست قرار می‌گیرند. برای سرویس‌های سیستم، فایل‌های پیکربندی باید در /lib/systemd/system/ قرار بگیرند؛ در حالی که سرویس‌های سفارشی یا Overrideها باید در /etc/systemd/system/ باشند. این تمایز مهم است تا تضمین شود پیکربندی‌های سفارشی بر پیش‌فرض‌های سیستم اولویت دارند.

برای چک کردن مکان و سینتکس فایل سرویس، از دستورات زیر استفاده کنید:

sudo systemctl status httpd
sudo systemctl cat httpd

دستور اول وضعیت سرویس—including هر پیام خطایی که ممکن است مشکل را نشان دهد—را نمایش می‌دهد. دستور دوم محتوای فایل سرویس را نمایش می‌دهد؛ که به شما اجازه بازرسی فایل برای خطاهای سینتکس یا وابستگی‌های نادرست را می‌دهد.

مسائل مجوز (مثلاً نیاز به sudo)

مسائل مجوز می‌توانند هنگام تلاش برای مدیریت سرویس‌ها بدون دسترسی‌های کافی بروز کنند. مطمئن شوید دستورات systemctl را با مجوزهای لازم—معمولاً با پیش‌گذاشتن sudo—اجرا می‌کنید. این به‌ویژه هنگام تغییر فایل‌های سیستم یا انجام اقداماتی که دسترسی‌های ارتقایافته لازم دارند مهم است.

مثلاً برای Reload کردن سرویس httpd با مجوزهای لازم، از دستور زیر استفاده کنید:

sudo systemctl reload httpd

فایل‌های یونیت بدجای‌گذاری‌شده یا نامعتبر

فایل‌های یونیت بدجای‌گذاری‌شده یا نامعتبر می‌توانند هنگام تلاش برای مدیریت سرویس‌ها به خطا منجر شوند. تأیید کنید فایل‌های یونیت درست در دایرکتوری‌های /etc/systemd/system/ یا /lib/systemd/system/ قرار دارند و درست فرمت شده‌اند. اگر فایل‌های یونیت سفارشی ساخته‌اید، مطمئن شوید درست نام‌گذاری شده و از سینتکس مورد انتظار پیروی می‌کنند.

برای تأیید مکان و فرمت فایل یونیت، از دستورات زیر استفاده کنید:

sudo systemctl list-unit-files
sudo systemctl cat <service_name>

دستور اول همه فایل‌های یونیت—including وضعیتشان—را فهرست می‌کند. دستور دوم محتوای فایل یونیت خاصی را نمایش می‌دهد؛ که به شما اجازه بازرسی فرمت و سینتکسش را می‌دهد.

سوالات متداول

۱. systemctl در لینوکس برای چیست؟

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

۲. چطور سرویس systemd را شروع یا متوقف کنم؟

برای شروع سرویس systemd، از دستور start همراه نام سرویس استفاده کنید. مثلاً برای شروع سرویس httpd:

sudo systemctl start httpd

برای متوقف کردن سرویس systemd، از دستور stop همراه نام سرویس استفاده کنید. مثلاً برای توقف سرویس httpd:

sudo systemctl stop httpd

۳. دستور systemctl enable چه می‌کند؟

دستور enable برای فعال کردن سرویس systemd جهت شروع خودکار هنگام بوت استفاده می‌شود. مثلاً برای فعال کردن سرویس httpd برای شروع هنگام بوت:

sudo systemctl enable httpd

این دستور Symlinkهایی به فایل سرویس در دایرکتوری /etc/systemd/system می‌سازد که باعث می‌شود سرویس هنگام بوت شروع شود.

۴. چطور بفهمم سرویسی اجرا می‌شود؟

برای چک کردن اینکه آیا سرویس systemd اجرا می‌شود، از دستور status همراه نام سرویس استفاده کنید. مثلاً برای چک کردن وضعیت سرویس httpd:

sudo systemctl status httpd

این دستور وضعیت فعلی سرویس—including اینکه اجرا می‌شود یا نه—را نمایش می‌دهد.

۵. تفاوت restart و reload در systemctl چیست؟

دستور restart سرویس را متوقف و سپس شروع می‌کند؛ که عملاً پیکربندی سرویس را Reload می‌کند. مثلاً برای ری‌استارت سرویس httpd:

sudo systemctl restart httpd

دستور reload از طرف دیگر، پیکربندی سرویس را بدون متوقف کردن سرویس Reload می‌کند. این وقتی مفید است که تغییراتی در فایل‌های پیکربندی سرویس داده‌اید و می‌خواهید آن تغییرات را بدون مختل کردن سرویس اعمال کنید. مثلاً برای Reload کردن سرویس httpd:

sudo systemctl reload httpd

نتیجه‌گیری

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

در حالی که systemctl عمدتاً با پروسه هسته systemd کار می‌کند، اجزای دیگری هم در اکوسیستم systemd وجود دارند که توسط ابزارهای دیگر کنترل می‌شوند. قابلیت‌های دیگر، مثل مدیریت لاگ و نشست‌های کاربر، توسط دیمن‌ها و ابزارهای مدیریت جداگانه مدیریت می‌شوند (به‌ترتیب journald/journalctl و logind/loginctl). وقتی گذاشتن برای آشنایی با این ابزارها و دیمن‌های دیگر، مدیریت را کار آسان‌تری می‌کند.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

همچنین ببینید
بستن
دکمه بازگشت به بالا