اجرای کدهای python در لینوکس با استفاده از systemd

صوت مساله بسیار ساده‌ست، ما کد pythonمون رو نوشتیم، تست کردیم، حالا می‌خوایم بذاریمش یک گوشه به شکل دائم اجرا شه.
حداقل خواستمون اینه که:

۱− موقع روشن شدن سیستم کد به شکل خودکار اجرا شه
۲- اگر در هر صورت خطایی رخ داد که باعث کرش کردن برنامه شد به شکل خودکار کدمون مجددا راه اندازی شده

در بین همه‌ی گزینه‌های ممکن برای انجام این کار systemd راحت‌ترین و سرراست ترین راه رسیدن به خواسته‌های بالاست و کیه که ندونه من چقدر تنبلی رو دوست دارم!

پس با من همراه باشید تا در ادامه‌ی این آموزش آسون‌ترین راه ممکن برای اجرای اتوماتیک کدهای pytohn رو با هم یاد بگیریم.

ایجاد یک برنامه‌ی نمونه:

اول یک برنامه ساده درست کنیم که صرفا یک متن رو در یک حلقه‌ی بینهایت هر یک دقیقه یک بار در انتهای یک فایل اضافه کنه:

#!/usr/bin/python
from time import sleep


if __name__ == "__main__":
    n = 0
    while True:
        n += 1
        with open("/dos/codes/systemd_demo.txt", "a") as file:
            # get further user input/do stuff here
            file.write(f"{n} mississippi\n")
        sleep(1)

این برنامه رو به اسم systemd_demo.py ذخیره می‌کنیم.

اگر کد برنامه رو اجرا کنیم یک فایل به اسم systemd_demo.txt ایجاد خواهد شد:

دقت کنید که برای اجرای این کد از آدرس کامل محیط آناکوندام و آدرس فایلم استفاده کردم، در مرحله‌ی بعد به این آدرس کامل احتیاج داریم.

هشدار: حتما یک بار توی ترمینال آدرس کامل رو بزنید و برنامه رو اجرا کنید، به خاطر ساختار import کردن ماژول‌ها و … در python ممکنه کد شما وقتی این شکلی اونو فرا می‌خونی با مشکل مواجه شه.

ایجاد فایل service:

با ویرایشگر دلخواهتون یک فایل با اسم مورد نظر خودتون (که مرتبط با اسم برنامه‌ای شما باشه) در آدرس /lib/systemd/system/و با پسوند .serviceایجاد کنید.

من از ویرایشگر nano استفاده می‌کنم، اگر nano رو نصب دارید کافیه در دستور زیر جای YOUR_SERVICE_NAME اسم مورد نظر خودتون رو بذارید.

sudo nano /lib/systemd/system/YOUR_SERVICE_NAME.service

ساختار کلی‌ای که برای ایجاد یک service لازم داریم به شکل زیره:

[Unit]
Description=YOUR SERVICE DESCRIPTION FOR HUMANS
After=multi-user.target
[email protected]

[Service]
Type=simple
ExecStart=YOUR PYTHON CODE EXECUTE COMMAND
StandardInput=tty-force
RemainAfterExit=yes
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

در ساختار بالا:

− بجای YOUR SERVICE DESCRIPTION FOR HUMANS توضیحات مرتبط با اینکه این کد/سرویس چی هست رو می‌نویسیم.

− بجای YOUR PYTHON CODE EXECUTE COMMAND دستور اجرای فایل خودمون وارد می‌کنیم.

− اگر می‌خوایم بعد از اتمام حلقه‌ی اصلی برنامه python اون service فعال بمونه مقدار RemainAfterExit رو برابر yes قرار می‌دیم.

− همچنین پارامتر RestartSec مقدار تاخیر هنگام اجرای مجدد کدمون رو مشخص می‌کنه.

ساختار فایل بالا رو من برای انجام برنامه‌ی مثال این پست به شکل زیر ویرایش کردم:

فعال سازی و اجرای service:

هر بار که ما در آدرس /lib/systemd/system/ فایلی می‌سازیم و یا در اون فایل‌ها تغییری ایجاد می‌کنیم نیازه تا systemctl رو راه اندازی مجدد کنیم تا تغییراتمون اعمال بشن، این کار با دستور زیر انجام می‌شه:

sudo systemctl daemon-reload

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

#To enable running service
sudo systemctl enable YOUR_SERVICE_NAME.service

#To stop running service
sudo systemctl stop YOUR_SERVICE_NAME.service

#To start running service
sudo systemctl start YOUR_SERVICE_NAME.service

#To restart running service
sudo systemctl restart YOUR_SERVICE_NAME.service

اگر همه‌چیز به خوبی پیش رفته باشه چنین خروجی‌ای خواهید دید و دیتا شروع می‌کنه وارد فایل systemd_demo.txt شدن.

منابع:

Auto-recovery of crashed services with systemd

How To Setup Autorun a Python Script Using Systemd

Writing a systemd Service in Python

https://stackoverflow.com/questions/44136655/why-standardinput-tty-in-oneshot-systemd-unit-files


نویسنده: محمد حسین سالاری

You may also like

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

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