SYSTEMD.SERVICE(5)

الاسم
systemd.service - ضبط وحدة الخدمة

موجز

service.service

الوصف

ملف ضبط الوحدة الذي ينتهي اسمه بـ ".service" يرمز معلومات عن عملية يتحكم فيها systemd ويشرف عليها.

تدرج صفحة الدليل هذه خيارات الضبط الخاصة بنوع هذه الوحدة. راجع systemd.unit(5) للخيارات المشتركة لجميع ملفات ضبط الوحدات. تضبط عناصر الضبط المشتركة في القسمين العامين [Unit] و [Install]. وتضبط خيارات الضبط الخاصة بالخدمة في قسم [Service].

تدرج خيارات إضافية في systemd.exec(5)، والتي تحدد بيئة التنفيذ التي تنفذ فيها الأوامر، وفي systemd.kill(5)، والتي تحدد الطريقة التي تنهى بها عمليات الخدمة، وفي systemd.resource-control(5)، والتي تضبط إعدادات التحكم في الموارد لعمليات الخدمة.

يسمح الأمر systemd-run(1) بإنشاء وحدات .service و .scope آليًا وعابرًا من سطر الأوامر.

قوالب الخدمة

يمكن لخدمات systemd أن تأخذ معاملًا واحدًا عبر صيغة "service@argument.service". تسمى هذه الخدمات خدمات "مجسدة"، بينما يسمى تعريف الوحدة بدون معامل argument بـ "القالب". يمكن أن يكون المثال قالب الخدمة dhcpcd@.service الذي يأخذ واجهة شبكة كمعامل لتشكيل خدمة مجسدة. داخل ملف الخدمة، يمكن الوصول إلى هذا المعامل أو "اسم التجسيد" باستخدام محددات %. راجع systemd.unit(5) للتفاصيل.

اعتمادات آلية

  التبعيات الضمنية

تُضاف التبعيات التالية ضمنيًا:

    • الخدمات المضبطة بـ Type=dbus تكتسب آليًا اعتماديات من نوع Requires= و After= على dbus.socket.

    • ترتب الخدمات المنشطة بالمقبس آليًا بعد وحدات .socket المنشطة لها عبر اعتمادية After= آلية. تجلب الخدمات أيضًا جميع وحدات .socket المدرجة في Sockets= عبر اعتماديات Wants= و After= آلية.

قد تُضاف اعتماديات ضمنية إضافية نتيجةً لمعاملات التنفيذ والتحكم في الموارد كما وُثقت في systemd.exec(5) و systemd.resource-control(5).

  الاعتمادات المبدئية

تُضاف الاعتماديات التالية ما لم يُضبط DefaultDependencies=no:

    • سيكون لوحدات الخدمة اعتماديات من نوع Requires= و After= على sysinit.target، واعتمادية من نوع After= على basic.target بالإضافة إلى اعتماديات من نوع Conflicts= و Before= على shutdown.target. تضمن هذه أن وحدات الخدمة العادية تجلب التهيئة الأساسية للنظام، وتُنهى بنظافة قبل إيقاف تشغيل النظام. يجب فقط على الخدمات المشاركة في بدء التشغيل المبكر أو إيقاف تشغيل النظام المتأخر تعطيل هذا الخيار.

    • تُخصص وحدات الخدمة المجسدة (أي وحدات الخدمة التي تحتوي على "@" في اسمها) مبدئيًا وحدة شريحة لكل قالب (راجع systemd.slice(5))، تُسمى باسم وحدة القالب، وتحتوي على جميع تجسيدات هذا القالب المحدد. تُوقف هذه الشريحة عادةً عند إيقاف التشغيل، جنبًا إلى جنب مع جميع تجسيدات القالب. إذا لم يكن ذلك مرغوبًا، فاضبط DefaultDependencies=no في وحدة القالب، وإما أن تحدد ملف وحدة شريحة خاص بك لكل قالب يضبط أيضًا DefaultDependencies=no، أو اضبط Slice=system.slice (أو شريحة أخرى مناسبة) في وحدة القالب. راجع أيضًا systemd.resource-control(5).

الخيارات

قد تتضمن ملفات وحدات الخدمة قسمي [Unit] و [Install]، الموصوفين في systemd.unit(5).

يجب أن تتضمن ملفات وحدات الخدمة قسم [Service]، والذي يحمل معلومات عن الخدمة والعملية التي تشرف عليها. تشترك عدد من الخيارات التي يمكن استخدامها في هذا القسم مع أنواع الوحدات الأخرى. توثق هذه الخيارات في systemd.exec(5) و systemd.kill(5) و systemd.resource-control(5). الخيارات الخاصة بقسم [Service] لوحدات الخدمة هي التالية:

Type=
    يضبط الآلية التي تخطر الخدمة من خلالها المدير بأن بدء تشغيل الخدمة قد انتهى. أحد الخيارات: simple، أو exec، أو forking، أو oneshot، أو dbus، أو notify، أو notify-reload، أو idle:

        • إذا ضُبط على simple (المبدئي إذا حُدد ExecStart= ولم يُحدد لا Type= ولا BusName=، ولم تُستخدم أوراق الاعتماد)، فإن مدير الخدمة سيعتبر الوحدة مبدوءة فورًا بعد تفرع عملية الخدمة الرئيسة (أي فورًا بعد fork()، وقبل ضبط سمات العملية المختلفة وبخاصة قبل أن تستدعي العملية الجديدة execve() لاستدعاء ثنائي الخدمة الفعلي). عادةً، يكون Type=exec هو الخيار الأفضل، انظر أدناه.

        يُتوقع أن تكون العملية المضبطة بـ ExecStart= هي العملية الرئيسة للخدمة. في هذا الوضع، إذا كانت العملية توفر وظائف لعمليات أخرى على النظام، فينبغي تثبيت قنوات اتصالها قبل بدء تشغيل الخدمة (مثل المقابس التي يُعدها systemd، عبر تنشيط المقبس)، حيث سيتابع مدير الخدمة فورًا بدء تشغيل الوحدات اللاحقة، مباشرة بعد إنشاء عملية الخدمة الرئيسة، وقبل تنفيذ ثنائي الخدمة. لاحظ أن هذا يعني أن أسطر أوامر systemctl start للخدمات من النوع simple ستُبلغ عن النجاح حتى لو تعذر استدعاء ثنائي الخدمة بنجاح (على سبيل المثال لأن User= المحدد غير موجود، أو أن ثنائي الخدمة مفقود).

        • النوع exec مشابه لـ simple، لكن مدير الخدمة سيعتبر الوحدة مبدوءة فورًا بعد تنفيذ ثنائي الخدمة الرئيس. سيؤخر مدير الخدمة بدء تشغيل الوحدات اللاحقة حتى تلك النقطة. (أو بعبارة أخرى: يتابع simple الوظائف الإضافية مباشرة بعد عودة fork()، بينما لن يتابع exec قبل نجاح كل من fork() و execve() في عملية الخدمة.) لاحظ أن هذا يعني أن أسطر أوامر systemctl start لخدمات exec ستُبلغ عن الفشل عندما يتعذر استدعاء ثنائي الخدمة بنجاح (على سبيل المثال لأن User= المحدد غير موجود، أو أن ثنائي الخدمة مفقود). يُضمن هذا النوع ضمناً إذا استخدمت أوراق الاعتماد (راجع LoadCredential= في systemd.exec(5) للتفاصيل).

        • إذا ضُبط على forking، سيعتبر المدير الوحدة مبدوءة فورًا بعد خروج الثنائي الذي تفرع بواسطة المدير. لا يُنصح باستخدام هذا النوع، استخدم notify، أو notify-reload، أو dbus بدلاً من ذلك.

        يُتوقع أن تستدعي العملية المضبطة بـ ExecStart= الدالة fork() كجزء من بدء تشغيلها. يُتوقع أن تخرج العملية الأب عند اكتمال بدء التشغيل وإعداد جميع قنوات الاتصال. يستمر الابن في العمل كعملية الخدمة الرئيسة، وسيعتبر مدير الخدمة الوحدة مبدوءة عندما تخرج العملية الأب. هذا هو سلوك خدمات UNIX التقليدية. إذا استخدم هذا الإعداد، يوصى أيضًا باستخدام خيار PIDFile=، حتى يتمكن systemd من تحديد العملية الرئيسة للخدمة بشكل موثوق. سيتابع المدير بدء تشغيل الوحدات اللاحقة بعد خروج العملية الأب.

        • سلوك oneshot مشابه لـ exec؛ ومع ذلك، سيعتبر مدير الخدمة الوحدة قائمة بعد خروج العملية الرئيسة. سيقوم بعد ذلك ببدء تشغيل الوحدات اللاحقة. يكون RemainAfterExit= مفيدًا بشكل خاص لهذا النوع من الخدمات. يكون Type=oneshot هو المبدئي الضمني إذا لم يُحدد لا Type= ولا ExecStart=. لاحظ أنه إذا استخدم هذا الخيار بدون RemainAfterExit= فلن تدخل الخدمة أبدًا في حالة الوحدة "نشط"، بل ستنتقل مباشرة من "جاري التنشيط" إلى "جاري إلغاء التنشيط" أو "ميت"، بما أنه لم تُضبط أي عملية لتعمل بشكل مستمر. يعني هذا على وجه الخصوص أنه بعد تشغيل خدمة من هذا النوع (ولم يُضبط فيها RemainAfterExit=) فلن تظهر كمبدوءة بعد ذلك، بل كميتة.

        • سلوك dbus مشابه لـ simple؛ ومع ذلك، يجب أن يكون لوحدات هذا النوع اسم ناقل محدد في BusName= وسيعتبر مدير الخدمة الوحدة قائمة عند الاستحواذ على اسم الناقل المحدد. هذا النوع هو المبدئي إذا حُدد BusName=.

        تكتسب وحدات الخدمة المضبطة بهذا الخيار ضمنيًا اعتماديات على وحدة dbus.socket. تُعتبر وحدة الخدمة من هذا النوع في حالة التنشيط حتى يُستحوذ على اسم الناقل المحدد. وتُعتبر منشطة طالما أن اسم الناقل مأخوذ. وبمجرد تحرير اسم الناقل، تُعتبر الخدمة غير صالحة للعمل مما يؤدي إلى محاولة مدير الخدمة إنهاء أي عمليات متبقية تنتمي للخدمة. وبالتالي ينبغي للخدمات التي تتخلى عن اسم ناقلها كجزء من منطق إيقاف تشغيلها أن تكون مستعدة لتلقي إشارة SIGTERM (أو أي إشارة مضبطة في KillSignal=) نتيجة لذلك.

        • سلوك notify مشابه لـ exec؛ ومع ذلك، يُتوقع أن ترسل الخدمة رسالة إشعار "READY=1" عبر sd_notify(3) أو استدعاء مكافئ عندما تنتهي من بدء التشغيل. سيتابع systemd بدء تشغيل الوحدات اللاحقة بعد إرسال رسالة الإشعار هذه. إذا استخدم هذا الخيار، ينبغي ضبط NotifyAccess= (انظر أدناه) لفتح الوصول إلى مقبس الإشعارات الموفر من systemd. إذا كان NotifyAccess= مفقودًا أو ضُبط على none، فسيُضبط قسرًا على main.

        إذا كانت الخدمة تدعم إعادة التحميل، وتستخدم إشارة لبدء إعادة التحميل، فيوصى باستخدام notify-reload بدلاً من ذلك.

        • سلوك notify-reload مشابه لـ notify، مع اختلاف واحد: تُرسل إشارة عملية UNIX وهي SIGHUP إلى العملية الرئيسة للخدمة عندما يُطلب من الخدمة إعادة التحميل وسينتظر المدير إشعارًا بشأن انتهاء إعادة التحميل.

        عند بدء عملية إعادة التحميل، يُتوقع من الخدمة الرد برسالة إشعار عبر sd_notify(3) تحتوي على الحقل "RELOADING=1" بالاقتران مع ضبط "MONOTONIC_USEC=" على الوقت الرتيب الحالي (أي CLOCK_MONOTONIC في clock_gettime(2)) بالميكروثانية، منسقًا كسلسلة عشرية. وبمجرد اكتمال إعادة التحميل، يجب إرسال رسالة إشعار أخرى تحتوي على "READY=1". يعد استخدام نوع الخدمة هذا وتطبيق بروتوكول إعادة التحميل هذا بديلًا فعالاً لتوفير أمر ExecReload= لإعادة تحميل ضبط الخدمة.

        يمكن تعديل الإشارة المراد إرسالها عبر ReloadSignal=، انظر أدناه.

        • سلوك idle مشابه جدًا لـ simple؛ ومع ذلك، يُؤجج التنفيذ الفعلي لبرنامج الخدمة حتى تُرسل جميع الوظائف النشطة. يمكن استخدام هذا لتجنب تداخل مخرجات خدمات الصدفة مع مخرجات الحالة على الطرفية. لاحظ أن هذا النوع مفيد فقط لتحسين مخرجات الطرفية، وليس مفيدًا كأداة عامة لترتيب الوحدات، ويخضع تأثير نوع الخدمة هذا لمهلة مدتها 5 ثوانٍ، يُستدعى بعدها برنامج الخدمة على أي حال.

    يوصى باستخدام Type=exec للخدمات طويلة التشغيل، لأنه يضمن تتبع أخطاء إعداد العملية (مثل أخطاء مثل ملف الخدمة التنفيذي المفقود، أو المستخدم المفقود) بشكل صحيح. ومع ذلك، نظراً لأن نوع الخدمة هذا لن ينشر الإخفاقات في كود بدء التشغيل الخاص بالخدمة نفسها (على عكس الإخفاقات في الخطوات التحضيرية التي ينفذها مدير الخدمة قبل execve()) ولا يسمح بترتيب الوحدات الأخرى مقابل اكتمال تهيئة كود الخدمة نفسه (وهو أمر مفيد على سبيل المثال إذا كان العملاء بحاجة إلى الاتصال بالخدمة من خلال شكل من أشكال IPC، وقناة IPC لا تُنشأ إلا بواسطة الخدمة نفسها — على نقيض القيام بذلك مسبقًا من خلال تنشيط المقبس أو الناقل أو ما شابه)، فقد لا يكون كافيًا في كثير من الحالات. إذا كان الأمر كذلك، فإن notify، أو notify-reload، أو dbus (الأخير فقط في حالة توفير الخدمة لواجهة D-Bus) هي الخيارات المفضلة لأنها تسمح لكود برنامج الخدمة بجدولة الوقت المحدد لاعتبار الخدمة قد بدأت بنجاح وموعد المتابعة مع الوحدات اللاحقة. تتطلب أنواع الخدمة notify/notify-reload دعمًا صريحًا في كود الخدمة (حيث يلزم استدعاء sd_notify() أو واجهة برمجة تطبيقات مكافئة بواسطة الخدمة في الوقت المناسب) — وإذا لم تكن مدعومة، فإن forking هو البديل: حيث يدعم بروتوكول بدء تشغيل خدمات UNIX التقليدي الثقيل. لاحظ أن استخدام أي نوع آخر غير simple قد يؤخر عملية بدء التشغيل، حيث يحتاج مدير الخدمة إلى انتظار اكتمال بعض تهيئات الخدمة على الأقل. (لاحظ أيضًا أنه لا يوصى عمومًا باستخدام idle أو oneshot للخدمات طويلة التشغيل.)

    لاحظ أن إعدادات الخدمة المختلفة (مثل User= و Group= من خلال libc NSS) قد تؤدي إلى استدعاءات IPC حاجزة "مخفية" لخدمات أخرى عند استخدامها. في بعض الأحيان قد يكون من المستحسن استخدام نوع الخدمة simple لضمان عدم تأثر منطق معاملات مدير الخدمة بمثل هذه العمليات البطيئة المحتملة والاعتماديات المخفية، لأن هذا هو نوع الخدمة الوحيد الذي لن ينتظر فيه مدير الخدمة اكتمال عمليات إعداد تنفيذ الخدمة هذه قبل المتابعة.

ExitType=
    يحدد متى ينبغي للمدير أن يعتبر الخدمة قد انتهت. أحد الخيارين: main أو cgroup:

        • إذا ضُبط على main (المبدئي)، فإن مدير الخدمة سيعتبر الوحدة متوقفة عندما تخرج العملية الرئيسة، والتي تُحدد وفقًا لـ Type=. وبالتالي، لا يمكن استخدامه مع Type=oneshot.

        • إذا ضُبط على cgroup، ستُعتبر الخدمة تعمل طالما أن عملية واحدة على الأقل في الـ cgroup لم تخرج.

    يوصى عمومًا باستخدام ExitType=main عندما يكون للخدمة نموذج تفرع معروف ويمكن تحديد العملية الرئيسة بشكل موثوق. إن ExitType= cgroup مخصص للتطبيقات التي لا يُعرف نموذج تفرعها مسبقًا والتي قد لا يكون لها عملية رئيسة محددة. وهو مناسب تمامًا للخدمات العابرة أو المُولدة آليًا، مثل التطبيقات الرسومية داخل بيئة سطح المكتب.

    أُضيف في الإصدار 250.

RemainAfterExit=
    يأخذ قيمة منطقية تحدد ما إذا كانت الخدمة ستُعتبر نشطة حتى عندما تخرج جميع عملياتها. القيمة المبدئية هي no.

GuessMainPID=
    يأخذ قيمة منطقية تحدد ما إذا كان ينبغي لـ systemd محاولة تخمين معرف العملية (PID) الرئيس للخدمة إذا تعذر تحديده بشكل موثوق. يُتجاهل هذا الخيار ما لم يُضبط Type=forking ويكون PIDFile= غير مضبط لأنه بالنسبة للأنواع الأخرى أو مع ملف PID مضبط صراحةً، يكون المعرف PID الرئيس معروفًا دائمًا. قد تصل خوارزمية التخمين إلى استنتاجات غير صحيحة إذا كان العفريت يتكون من أكثر من عملية واحدة. إذا تعذر تحديد المعرف PID الرئيس، فلن يعمل كشف الفشل وإعادة التشغيل الآلي للخدمة بشكل موثوق. القيمة المبدئية هي yes.

PIDFile=
    يأخذ مسارًا يشير إلى ملف PID للخدمة. يوصى باستخدام هذا الخيار للخدمات التي ضُبط فيها Type= على forking. يشير المسار المحدد عادةً إلى ملف تحت مجلد /run/. إذا حُدد مسار نسبي لخدمة النظام، فإنه يُسبق بـ /run/، ويُسبق بـ $XDG_RUNTIME_DIR إذا حُدد في خدمة مستخدم. سيقرأ مدير الخدمة المعرف PID للعملية الرئيسة للخدمة من هذا الملف بعد بدء تشغيل الخدمة. لن يكتب مدير الخدمة في الملف المضبط هنا، على الرغم من أنه سيحذف الملف بعد إيقاف تشغيل الخدمة إذا كان لا يزال موجودًا. لا يلزم أن يكون ملف PID مملوكًا لمستخدم متميز، ولكن إذا كان مملوكًا لمستخدم غير متميز فتُفرض قيود أمان إضافية: لا يجوز أن يكون الملف رابطًا رمزيًا لملف مملوك لمستخدم آخر (لا مباشرة ولا بشكل غير مباشر)، ويجب أن يشير ملف PID إلى عملية تنتمي بالفعل إلى الخدمة.

    لاحظ أنه ينبغي تجنب ملفات PID في المشاريع الحديثة. استخدم Type=notify، أو Type=notify-reload، أو Type=simple حيثما أمكن، والتي لا تتطلب استخدام ملفات PID لتحديد العملية الرئيسة للخدمة وتتجنب التفرع غير الضروري.

BusName=
    يأخذ اسم وجهة D-Bus الذي يجب على هذه الخدمة استخدامه. هذا الخيار إلزامي للخدمات التي ضُبط فيها Type= على dbus. يوصى بضبط هذه الخاصية دائمًا إذا كانت معروفة لتسهيل مطابقة اسم الخدمة مع وجهة D-Bus. وتستفيد أفعال systemctl service-log-level/service-log-target من هذا بشكل خاص.

ExecStart=
    الأوامر التي تنفذ عند بدء تشغيل هذه الخدمة.

    ما لم يكن Type= هو oneshot، يجب إعطاء أمر واحد بالضبط. عند استخدام Type=oneshot، يمكن استخدام هذا الإعداد مرات متعددة لتحديد أوامر متعددة للتنفيذ. إذا أُسندت السلسلة الفارغة لهذا الخيار، فستُصفر قائمة الأوامر المراد بدؤها، ولن يكون للإسنادات السابقة لهذا الخيار أي تأثير. إذا لم يُحدد ExecStart=، فيجب أن تحتوي الخدمة على RemainAfterExit=yes وسطر ExecStop= واحد على الأقل مضبط. (الخدمات التي تفتقر إلى كل من ExecStart= و ExecStop= غير صالحة.)

    إذا ضُبط أكثر من أمر واحد، تُستدعى الأوامر بالتتابع بالترتيب الذي تظهر به في ملف الوحدة. إذا فشل أحد الأوامر (ولم يكن مسبوقًا بـ "-")، فلن تُنفذ الأسطر الأخرى، وتُعتبر الوحدة فاشلة.

    ما لم يُضبط Type=forking، فإن العملية المبدوءة عبر سطر الأوامر هذا ستُعتبر العملية الرئيسة للعفريت.

ExecStartPre=، ExecStartPost=
    أوامر إضافية تنفذ قبل أو بعد الأمر الموجود في ExecStart=، على التوالي. الصيغة هي نفسها لـ ExecStart=. يُسمح بأسطر أوامر متعددة، بغض النظر عن نوع الخدمة (أي Type=)، وتُنفذ الأوامر واحدًا تلو الآخر بالتسلسل.

    إذا فشل أي من تلك الأوامر (غير المسبوقة بـ "-")، فلن يُنفذ الباقي وتُعتبر الوحدة فاشلة.

    لا تُشغل أوامر ExecStart= إلا بعد خروج جميع أوامر ExecStartPre= التي لم تكن مسبوقة بـ "-" بنجاح.

    لا تُشغل أوامر ExecStartPost= إلا بعد استدعاء الأوامر المحددة في ExecStart= بنجاح، كما هو محدد بواسطة Type= (أي أن العملية قد بُدئت لـ Type=simple أو Type=idle، أو خرجت آخر عملية ExecStart= بنجاح لـ Type=oneshot، أو خرجت العملية الأولية بنجاح لـ Type=forking، أو أُرسل "READY=1" لـ Type=notify/Type=notify-reload، أو أُخذ BusName= لـ Type=dbus).

    لاحظ أنه لا يجوز استخدام ExecStartPre= لبدء عمليات طويلة التشغيل. سيقضى على جميع العمليات المتفرعة عن العمليات المستدعاة عبر ExecStartPre= قبل تشغيل عملية الخدمة التالية.

    لاحظ أنه إذا فشل أي من الأوامر المحددة في ExecStartPre=، أو ExecStart=، أو ExecStartPost= (ولم تكن مسبوقة بـ "-"، انظر أعلاه) أو انتهت مهلتها قبل أن تقوم الخدمة تمامًا، يستمر التنفيذ بالأوامر المحددة في ExecStopPost=، وتُتخطى الأوامر في ExecStop=.

    لاحظ أن تنفيذ ExecStartPost= يُؤخذ في الحسبان لغرض قيود الترتيب Before=/After=.

ExecCondition=
    أوامر اختيارية تنفذ قبل الأوامر الموجودة في ExecStartPre=. الصيغة هي نفسها لـ ExecStart=. يُسمح بأسطر أوامر متعددة، بغض النظر عن نوع الخدمة (أي Type=)، وتُنفذ الأوامر واحدًا تلو الآخر بالتسلسل.

    السلوك يشبه هجينًا من ExecStartPre= وفحص الشرط: عندما يخرج أمر ExecCondition= برمز خروج من 1 إلى 254 (شاملاً)، تُتخطى الأوامر المتبقية ولا تُعلم الوحدة كفاشلة. ومع ذلك، إذا خرج أمر ExecCondition= برمز 255 أو بشكل غير طبيعي (مثل انتهاء المهلة، أو القضاء عليه بإشارة، إلخ)، ستُعتبر الوحدة فاشلة (وستُتخطى الأوامر المتبقية). رمز الخروج 0 أو الرموز التي تطابق SuccessExitStatus= ستواصل التنفيذ إلى الأوامر التالية.

    تنطبق نفس التوصيات بشأن عدم تشغيل عمليات طويلة التشغيل في ExecStartPre= أيضًا على ExecCondition=. سيقوم ExecCondition= أيضًا بتشغيل الأوامر في ExecStopPost=، كجزء من إيقاف الخدمة، في حال حدوث أي خروج غير صفري أو غير طبيعي، مثل تلك الموصوفة أعلاه.

    أُضيف في الإصدار 243.

ExecReload=
    الأوامر المراد تنفيذها لإطلاق إعادة تحميل الضبط في الخدمة. قد يأخذ هذا الإعداد أسطر أوامر متعددة، باتباع المخطط نفسه الموصوف لـ ExecStart= أعلاه. استخدام هذا الإعداد اختياري. استبدال المحددات ومتغيرات البيئة مدعوم هنا باتباع المخطط نفسه لـ ExecStart=.

    يُضبط متغير بيئة إضافي وخاص: إذا كان معروفًا، يُضبط $MAINPID على العملية الرئيسة للعفريت، ويمكن استخدامه لأسطر أوامر مثل التالي:

        ExecReload=kill -HUP $MAINPID

    لاحظ مع ذلك أن إعادة تحميل عفريت عن طريق إدراج إشارة في الطابور دون إشعار بالاكتمال (كما هو الحال مع السطر المثالي أعلاه) ليس خيارًا جيدًا عادةً، لأن هذه عملية غير متزامنة وبالتالي فهي غير مناسبة عند ترتيب إعادات تحميل خدمات متعددة ضد بعضها البعض. لذا يوصى بشدة إما باستخدام Type=notify-reload، أو ضبط ExecReload= على أمر لا يطلق فقط إعادة تحميل ضبط العفريت، بل ينتظر أيضًا بشكل متزامن اكتماله. على سبيل المثال، يستخدم dbus-broker(1) التالي:

        ExecReload=busctl call org.freedesktop.DBus \
                /org/freedesktop/DBus org.freedesktop.DBus \
                ReloadConfig

    يمكن دمج هذا الإعداد مع Type=notify-reload، وفي هذه الحالة تُرسل الإشارة إلى العملية الرئيسة للخدمة بعد انتهاء تنفيذ جميع أسطر الأوامر المحددة. وعلى وجه الخصوص، إذا استُقبل إشعار "RELOADING=1" قبل اكتمال ExecReload=، فيتُخطى إرسال الإشارة ويبدأ مدير الخدمة فورًا في الاستماع لـ "READY=1".

ExecReloadPost=
    الأوامر المراد تنفيذها بعد عملية إعادة تحميل ناجحة. صيغة هذا الإعداد هي تمامًا نفس صيغة ExecReload=.

    أُضيف في الإصدار 259.

ExecStop=
    الأوامر المراد تنفيذها لإيقاف الخدمة المبدوءة عبر ExecStart=. يأخذ هذا المعامل أسطر أوامر متعددة، باتباع المخطط نفسه الموصوف لـ ExecStart= أعلاه. استخدام هذا الإعداد اختياري. بعد تشغيل الأوامر المضبطة في هذا الخيار، يُفهم ضمنيًا أن الخدمة قد توقفت، وتُنهى أي عمليات متبقية لها وفقًا لإعداد KillMode= (راجع systemd.kill(5)). إذا لم يُحدد هذا الخيار، تُنهى العملية بإرسال الإشارة المحددة في KillSignal= أو RestartKillSignal= عند طلب إيقاف الخدمة. استبدال المحددات ومتغيرات البيئة مدعوم (بما في ذلك $MAINPID، انظر أعلاه).

    لاحظ أنه لا يكفي عادةً تحديد أمر لهذا الإعداد يطلب فقط من الخدمة الإنهاء (على سبيل المثال، عن طريق إرسال شكل من أشكال إشارة الإنهاء إليها)، ولكنه لا ينتظر قيامها بذلك. نظرًا لأن العمليات المتبقية للخدمات تُقضى عليها وفقًا لـ KillMode= و KillSignal= أو RestartKillSignal= كما هو موصوف أعلاه فور خروج الأمر، فقد لا يؤدي هذا إلى إيقاف نظيف. لذا ينبغي أن يكون الأمر المحدد عملية متزامنة، وليس عملية غير متزامنة.

    لاحظ أن الأوامر المحددة في ExecStop= لا تُنفذ إلا عندما تبدأ الخدمة بنجاح أولاً. ولا تُستدعى إذا لم تُبدأ الخدمة أصلاً، أو في حال فشل بدء تشغيلها، على سبيل المثال لأن أيًا من الأوامر المحددة في ExecStart=، أو ExecStartPre=، أو ExecStartPost= قد فشل (ولم يكن مسبوقًا بـ "-"، انظر أعلاه) أو انتهت مهلته. استخدم ExecStopPost= لاستدعاء الأوامر عندما تفشل الخدمة في بدء التشغيل بشكل صحيح وتُغلق مجددًا. لاحظ أيضًا أن عملية الإيقاف تُنفذ دائمًا إذا بدأت الخدمة بنجاح، حتى لو انتهت العمليات في الخدمة من تلقاء نفسها أو قُضي عليها. يجب أن تكون أوامر الإيقاف مستعدة للتعامل مع تلك الحالة. سيُبطل ضبط $MAINPID إذا علم systemd أن العملية الرئيسة قد خرجت بحلول وقت استدعاء أوامر الإيقاف.

    تُنفذ طلبات إعادة تشغيل الخدم كعمليات إيقاف تليها عمليات بدء. هذا يعني أن ExecStop= و ExecStopPost= يُنفذان أثناء عملية إعادة تشغيل الخدمة.

    يوصى باستخدام هذا الإعداد للأوامر التي تتواصل مع الخدمة طالبةً إنهاءً نظيفًا. لخطوات التنظيف بعد الوفاة، استخدم ExecStopPost= بدلاً من ذلك.

ExecStopPost=
    أوامر إضافية تنفذ بعد إيقاف الخدمة. ويشمل ذلك الحالات التي استخدمت فيها الأوامر المضبطة في ExecStop=، أو عندما لا يكون للخدمة أي ExecStop= محدد، أو عندما تخرج الخدمة بشكل غير متوقع. يأخذ هذا المعامل أسطر أوامر متعددة، باتباع المخطط نفسه الموصوف لـ ExecStart=. استخدام هذه الإعدادات اختياري. استبدال المحددات ومتغيرات البيئة مدعوم. لاحظ أنه — على عكس ExecStop= — فإن الأوامر المحددة بهذا الإعداد تُستدعى عندما تفشل الخدمة في بدء التشغيل بشكل صحيح وتُغلق مجددًا.

    يوصى باستخدام هذا الإعداد لعمليات التنظيف التي يجب تنفيذها حتى عندما تفشل الخدمة في بدء التشغيل بشكل صحيح. يجب أن تكون الأوامر المضبطة بهذا الإعداد قادرة على العمل حتى لو فشلت الخدمة في بدء التشغيل في منتصف الطريق وتركت بيانات ملوثة غير مكتملة التهيئة من حولها. ونظراً لأن عمليات الخدمة قد خرجت بالفعل على الأرجح عند تنفيذ الأوامر المحددة بهذا الإعداد، فلا ينبغي لها محاولة الاتصال بها.

    لاحظ أن جميع الأوامر المضبطة بهذا الإعداد تُستدعى مع رمز نتيجة الخدمة، بالإضافة إلى رمز خروج وحالة العملية الرئيسة، المضبطة في متغيرات البيئة $SERVICE_RESULT و $EXIT_CODE و $EXIT_STATUS، راجع systemd.exec(5) للتفاصيل.

    لاحظ أن تنفيذ ExecStopPost= يُؤخذ في الحسبان لغرض قيود الترتيب Before=/After=.

RestartSec=
    يضبط وقت النوم قبل إعادة تشغيل الخدمة (كما هو مضبط بـ Restart=). يأخذ قيمة بدون وحدة بالثواني، أو قيمة فترة زمنية مثل "5min 20s". القيمة المبدئية هي 100ms.

RestartSteps=
    يضبط عدد الخطوات الأسية التي يجب اتخاذها لزيادة فاصل إعادات التشغيل الآلي من RestartSec= إلى RestartMaxDelaySec=. يأخذ عددًا صحيحًا موجبًا أو 0 لتعطيله. القيمة المبدئية هي 0. تلميح: القيم بين 3 و 5 هي خيارات جيدة عند الرغبة في التراجع الأسي.

    مثال:

        RestartSec=10s
        RestartSteps=4
        RestartMaxDelaySec=160s

    سيؤدي هذا إلى إنتاج فترات إعادة التشغيل التالية: 10ث، 20ث، 40ث، 80ث، 160ث، 160ث، 160ث، إلخ. لاحظ الاستكمال الهندسي والنسبة الثابتة الناتجة بين الفترات؛ وهي هنا 2. صيغة الـ ratio هي (RestartMaxDelaySec / RestartSec)^(1 / RestartSteps). يوصَل دائمًا إلى تأخير (متكرر) مساوٍ لـ RestartMaxDelaySec= بعد خطوتَين RestartSteps + 1.

    لا يكون هذا الإعداد فعالًا إلا إذا ضُبط RestartMaxDelaySec= أيضًا ولم يكن RestartSec= صفرًا.

    أُضيف في الإصدار 254.

RestartMaxDelaySec=
    يضبط أطول وقت للنوم قبل إعادة تشغيل الخدمة مع زيادة الفترة باستخدام RestartSteps=. يأخذ قيمة بنفس تنسيق RestartSec=، أو "infinity" لتعطيل الإعداد. القيمة المبدئية هي "infinity".

    لا يكون هذا الإعداد فعالًا إلا إذا ضُبط RestartSteps= أيضًا ولم يكن RestartSec= صفرًا.

    أُضيف في الإصدار 254.

TimeoutStartSec=
    يضبط وقت الانتظار لبدء التشغيل. إذا لم تُرسل خدمة العفريت إشعارًا بـ اكتمال بدء التشغيل خلال الوقت المضبوط، فستُعتبر الخدمة فاشلة وسيُعاد إغلاقها. يعتمد الإجراء الدقيق على الخيار TimeoutStartFailureMode=. يأخذ قيمة عديمة الوحدة بالثواني، أو قيمة فترة زمنية مثل "5min 20s". مرر "infinity" لتعطيل منطق مهلة الانتظار. القيمة المبدئية هي DefaultTimeoutStartSec= المضبوطة في المدير، باستثناء عند استخدام Type=oneshot، وفي هذه الحالة تُعطل مهلة الانتظار مبدئيًا (انظر systemd-system.conf(5)).

    إذا أرسلت خدمة من نوع Type=notify/Type=notify-reload الرسالة "EXTEND_TIMEOUT_USEC=..."، فقد يتسبب هذا في تمديد وقت بدء التشغيل بعد TimeoutStartSec=. يجب أن يحدث الاستلام الأول لهذه الرسالة قبل تجاوز TimeoutStartSec=، وبمجرد تمديد وقت بدء التشغيل بعد TimeoutStartSec=، سيسمح مدير الخدمة للخدمة بمواصلة بدء التشغيل، شريطة أن تكرر الخدمة "EXTEND_TIMEOUT_USEC=..." ضمن الفترة المحددة حتى تنتهي حالة بدء تشغيل الخدمة بواسطة "READY=1". (انظر sd_notify(3)).

    لاحظ أن مهلة بدء التشغيل تُطبق أيضًا على إعادات تحميل الخدمة، بغض النظر عما إذا نُفذت من خلال ExecReload= أو عبر منطق إعادة التحميل المُمكّن عبر Type=notify-reload. إذا لم تكتمل إعادة التحميل خلال الوقت المضبوط، فستُعتبر إعادة التحميل فاشلة وستستمر الخدمة في العمل بالتهيئة القديمة. لن يؤثر هذا على الخدمة المشغلة، ولكن سيُسجل في السجل وسيتسبب على سبيل المثال في فشل أمر systemctl reload.

    أُضيف في الإصدارة 188.

TimeoutStopSec=
    يخدم هذا الخيار غرضين. أولاً، يضبط وقت الانتظار لكل أمر ExecStop=. إذا انتهت مهلة أي منها، تُتخطى أوامر ExecStop= اللاحقة وتُنهى الخدمة بواسطة SIGTERM. إذا لم تُحدد أي أوامر ExecStop=، تتلقى الخدمة الإشارة SIGTERM فورًا. يمكن تغيير هذا السلوك المبدئي بواسطة الخيار TimeoutStopFailureMode=. ثانيًا، يضبط وقت الانتظار لتوقف الخدمة نفسها. إذا لم تنتهِ في الوقت المحدد، تُنهى قسريًا بواسطة SIGKILL (انظر KillMode= في systemd.kill(5)). يأخذ قيمة عديمة الوحدة بالثواني، أو قيمة فترة زمنية مثل "5min 20s". مرر "infinity" لتعطيل منطق مهلة الانتظار. القيمة المبدئية هي DefaultTimeoutStopSec= من ملف تهيئة المدير (انظر systemd-system.conf(5)).

    إذا أرسلت خدمة من نوع Type=notify/Type=notify-reload الرسالة "EXTEND_TIMEOUT_USEC=..."، فقد يتسبب هذا في تمديد وقت التوقف بعد TimeoutStopSec=. يجب أن يحدث الاستلام الأول لهذه الرسالة قبل تجاوز TimeoutStopSec=، وبمجرد تمديد وقت التوقف بعد TimeoutStopSec=، سيسمح مدير الخدمة للخدمة بمواصلة التوقف، شريطة أن تكرر الخدمة "EXTEND_TIMEOUT_USEC=..." ضمن الفترة المحددة، أو تنهي نفسها بنفسها (انظر sd_notify(3)).

    أُضيف في الإصدارة 188.

TimeoutAbortSec=
    يضبط هذا الخيار وقت الانتظار لإنهاء الخدمة عندما أُحبطت بسبب انتهاء مهلة مراقب الجرأة (انظر WatchdogSec=). إذا كان للخدمة مهلة TimeoutStopSec= قصيرة، فيمكن استخدام هذا الخيار لمنح النظام مزيدًا من الوقت لكتابة تفريغ الذاكرة الرئيس للخدمة. عند انتهاء الصلاحية، تُنهى الخدمة قسريًا بواسطة SIGKILL (انظر KillMode= في systemd.kill(5)). سيُبتر ملف الذاكرة الرئيس في هذه الحالة. استخدم TimeoutAbortSec= لضبط مهلة معقولة لتفريغ الذاكرة الرئيس لكل خدمة تكون كبيرة بما يكفي لكتابة جميع البيانات المتوقعة وفي نفس الوقت قصيرة بما يكفي لمعالجة فشل الخدمة في الوقت المناسب.

    يأخذ قيمة عديمة الوحدة بالثواني، أو قيمة فترة زمنية مثل "5min 20s". مرر قيمة فارغة لتخطي معالجة مهلة إحباط مراقب الجرأة المخصصة والرجوع إلى TimeoutStopSec=. مرر "infinity" لتعطيل منطق مهلة الانتظار. القيمة المبدئية هي DefaultTimeoutAbortSec= من ملف تهيئة المدير (انظر systemd-system.conf(5)).

    إذا كانت خدمة من نوع Type=notify/Type=notify-reload تعالج SIGABRT بنفسها (بدلاً من الاعتماد على النواة لكتابة تفريغ الذاكرة الرئيس)، فيمكنها إرسال "EXTEND_TIMEOUT_USEC=..." لتمديد وقت الإحباط بعد TimeoutAbortSec=. يجب أن يحدث الاستلام الأول لهذه الرسالة قبل تجاوز TimeoutAbortSec=، وبمجرد تمديد وقت الإحباط بعد TimeoutAbortSec=، سيسمح مدير الخدمة للخدمة بمواصلة الإحباط، شريطة أن تكرر الخدمة "EXTEND_TIMEOUT_USEC=..." ضمن الفترة المحددة، أو تنهي نفسها (انظر sd_notify(3)).

    أُضيف في الإصدار 243.

TimeoutSec=
    اختصار لضبط كل من TimeoutStartSec= و TimeoutStopSec= على القيمة المحددة.

TimeoutStartFailureMode=, TimeoutStopFailureMode=
    تضبط هذه الخيارات الإجراء المتخذ في حال لم تُرسل خدمة العفريت إشعارًا ببدء التشغيل ضمن مهلة TimeoutStartSec= المضبوطة لها، أو إذا لم تتوقف ضمن TimeoutStopSec= على التوالي. تأخذ أحد الخيارات terminate و abort و kill. كلا الخيارين قيمتهما المبدئية هي terminate.

    إذا ضُبط terminate، فستُنهى الخدمة بلطف عن طريق إرسال الإشارة المحددة في KillSignal= (المبدئي هو SIGTERM، انظر systemd.kill(5)). إذا لم تنتهِ الخدمة، تُرسل الإشارة FinalKillSignal= بعد TimeoutStopSec=. إذا ضُبط abort، تُرسل الإشارة WatchdogSignal= بدلاً من ذلك وتُطبق مهلة TimeoutAbortSec= قبل إرسال FinalKillSignal=. يمكن استخدام هذا الإعداد لتحليل الخدمات التي تفشل في بدء التشغيل أو الإغلاق بشكل متقطع. عند استخدام kill، تُنهى الخدمة فورًا عن طريق إرسال FinalKillSignal= دون أي مهلة إضافية. يمكن استخدام هذا الإعداد لتسريع إغلاق الخدمات الفاشلة.

    أُضيف في الإصدار 246.

RuntimeMaxSec=
    يضبط الحد الأقصى لوقت تشغيل الخدمة. إذا استُخدم هذا وكان الخدمة نشطة لفترة أطول من الوقت المحدد، تُنهى وتوضع في حالة فشل. لاحظ أن هذا الإعداد ليس له أي تأثير على خدمات Type=oneshot، لأنها تنتهي فورًا بعد اكتمال التنشيط (استخدم TimeoutStartSec= للحد من تنشيطها). مرر "infinity" (المبدئي) لتهيئة عدم وجود حد لوقت التشغيل.

    إذا أرسلت خدمة من نوع Type=notify/Type=notify-reload الرسالة "EXTEND_TIMEOUT_USEC=..."، فقد يتسبب هذا في تمديد وقت التشغيل بعد RuntimeMaxSec=. يجب أن يحدث الاستلام الأول لهذه الرسالة قبل تجاوز RuntimeMaxSec=، وبمجرد تمديد وقت التشغيل بعد RuntimeMaxSec=، سيسمح مدير الخدمة للخدمة بمواصلة العمل، شريطة أن تكرر الخدمة "EXTEND_TIMEOUT_USEC=..." ضمن الفترة المحددة حتى يتحقق إغلاق الخدمة بواسطة "STOPPING=1" (أو الإنهاء). (انظر sd_notify(3)).

    أُضيف في الإصدارة 229.

RuntimeRandomizedExtraSec=
    يعدل هذا الخيار RuntimeMaxSec= عن طريق زيادة الحد الأقصى لوقت التشغيل بمدة موزعة بالتساوي بين 0 والقيمة المحددة (بالثواني). إذا كان RuntimeMaxSec= غير محدد، فستُعطل هذه الميزة.

    أُضيف في الإصدار 250.

WatchdogSec=
    يضبط مهلة مراقب الجرأة للخدمة. يُنشط مراقب الجرأة عند اكتمال بدء التشغيل. يجب على الخدمة استدعاء sd_notify(3) بانتظام باستخدام "WATCHDOG=1" (أي "ping الإبقاء على الاتصال"). إذا كان الوقت بين استدعاءين من هذا القبيل أكبر من الوقت المضبوط، فستوضع الخدمة في حالة فشل وسيتم إنهاؤها بواسطة SIGABRT (أو الإشارة المحددة بواسطة WatchdogSignal=). عن طريق ضبط Restart= على on-failure أو on-watchdog أو on-abnormal أو always، ستُعاد تشغيل الخدمة آليًا. سيُمَرر الوقت المضبوط هنا إلى عملية الخدمة المنفذة في متغير البيئة WATCHDOG_USEC=. يتيح هذا للعفاريت تمكين منطق ping الإبقاء على الاتصال آليًا إذا كان دعم مراقب الجرأة مُمكّنًا للخدمة. إذا استُخدم هذا الخيار، فيجب ضبط NotifyAccess= (انظر أدناه) لفتح الوصول إلى مقبس الإشعارات الذي يوفره systemd. إذا لم يُضبط NotifyAccess=، فسيُضبط ضمنيًا على main. القيمة المبدئية هي 0، مما يعطل هذه الميزة. يمكن للخدمة التحقق مما إذا كان مدير الخدمة يتوقع إشعارات الإبقاء على الاتصال لمراقب الجرأة. انظر sd_watchdog_enabled(3) للتفاصيل. يمكن استخدام sd_event_set_watchdog(3) لتمكين دعم إشعارات مراقب الجرأة الآلي.

Restart=
    يحدد ما إذا كان يجب إعادة تشغيل الخدمة عند إنهاء عملية الخدمة أو إيقافها أو عند انتهاء المهلة. قد تكون عملية الخدمة هي عملية الخدمة الرئيسة، ولكنها قد تكون أيضًا إحدى العمليات المحددة بواسطة ExecStartPre= أو ExecStartPost= أو ExecStop= أو ExecStopPost= أو ExecReload=. عندما يكون توقف العملية نتيجة لعملية systemd (مثل إيقاف الخدمة أو إعادة تشغيلها)، لن يتم إعادة تشغيل الخدمة. تشمل فترات الانتظار انتهاء مهلة ”ping keep-alive“ الخاصة ببرنامج المراقبة، وفترات انتظار عمليات بدء الخدمة وإعادة تحميلها وإيقافها.

    يأخذ أحد الخيارات no أو on-success أو on-failure أو on-abnormal أو on-watchdog أو on-abort أو always. إذا ضُبط على no (المبدئي)، فلن تُعاد تشغيل الخدمة. إذا ضُبط على on-success، فستُعاد تشغيلها فقط عندما تخرج عملية الخدمة بشكل نظيف. في هذا السياق، يعني الخروج النظيف أيًا مما يلي:

        • رمز خروج بقيمة 0؛

        • للأنواع الأخرى بخلاف Type=oneshot، إحدى الإشارات SIGHUP أو SIGINT أو SIGTERM أو SIGPIPE؛

        • حالات الخروج والإشارات المحددة في SuccessExitStatus=.

    إذا ضُبط على on-failure، فستُعاد تشغيل الخدمة عندما تخرج العملية برمز خروج غير صفري، أو تُنهى بواسطة إشارة (بما في ذلك تفريغ الذاكرة الرئيس، ولكن باستثناء الإشارات الأربع المذكورة أعلاه)، أو عندما تنتهي مهلة عملية ما (مثل إعادة تحميل الخدمة)، وعند تشغيل مهلة مراقب الجرأة المضبوطة. إذا ضُبط على on-abnormal، فستُعاد تشغيل الخدمة عندما تُنهى العملية بواسطة إشارة (بما في ذلك تفريغ الذاكرة الرئيس، باستثناء الإشارات الأربع المذكورة أعلاه)، أو عندما تنتهي مهلة عملية ما، أو عند تشغيل مهلة مراقب الجرأة. إذا ضُبط على on-abort، فستُعاد تشغيل الخدمة فقط إذا خرجت عملية الخدمة بسبب إشارة غير ملتقطة لم تُحدد كحالة خروج نظيفة. إذا ضُبط على on-watchdog، فستُعاد تشغيل الخدمة فقط إذا انتهت مهلة مراقب الجرأة للخدمة. إذا ضُبط على always، فستُعاد تشغيل الخدمة بغض النظر عما إذا كانت قد خرجت بشكل نظيف أم لا، أو أُنهيت بشكل غير طبيعي بواسطة إشارة، أو واجهت مهلة انتظار. لاحظ أن خدمات Type=oneshot لن تُعاد تشغيلها أبدًا بناءً على حالة خروج نظيفة، أي أن الخيارين always و on-success مَرفوضان لها.

    جدول 1. أسباب الخروج وتأثير إعدادات Restart=
    إعدادات إعادة التشغيل/أسباب الخروج | no | always | on-success | on-failure | on-abnormal | on-abort | on-watchdog
    رمز خروج أو إشارة نظيفة |  | X | X |  |  |  |
    رمز خروج غير نظيف |  | X |  | X |  |  |
    إشارة غير نظيفة |  | X |  | X | X | X |
    المهلة |  | X |  | X | X |  |
    مراقب الجرأة |  | X |  | X | X |  | X
    الإنهاء بسبب نفاد الذاكرة (OOM) |  | X |  | X | X |  |

    كاستثناءات للإعداد أعلاه، لن تُعاد تشغيل الخدمة إذا حُدد رمز الخروج أو الإشارة في RestartPreventExitStatus= (انظر أدناه) أو إذا أُوقفت الخدمة باستخدام systemctl stop أو عملية مكافئة. وأيضًا، ستُعاد تشغيل الخدمات دائمًا إذا حُدد رمز الخروج أو الإشارة في RestartForceExitStatus= (انظر أدناه).

    لاحظ أن إعادة تشغيل الخدمة تخضع للحد من معدل بدء تشغيل الوحدة المهيأ بواسطة StartLimitIntervalSec= و StartLimitBurst=، انظر systemd.unit(5) للتفاصيل.

    يعد ضبط هذا على on-failure هو الخيار الموصى به للخدمات طويلة التشغيل، من أجل زيادة الموثوقية من خلال محاولة الاسترداد الآلي من الأخطاء. بالنسبة للخدمات التي يجب أن تكون قادرة على الإنهاء باختيارها الخاص (وتجنب إعادة التشغيل الفورية)، فإن on-abnormal هو خيار بديل.

RestartMode=
    يأخذ قيمة نصية تحدد كيفية إعادة تشغيل الخدمة:

        • إذا ضُبط على normal (المبدئي)، فإن الخدمة تُعاد تشغيلها بالمرور عبر حالة فاشلة/غير نشطة.

        أُضيف في الإصدار 254.

        • إذا ضُبط على direct، تنتقل الخدمة إلى حالة التنشيط مباشرة أثناء إعادة التشغيل الآلي، وتتخطى الحالة الفاشلة/غير النشطة. لا يزال يُستدعى ExecStopPost=. ويُتخطى OnSuccess= و OnFailure=.

        هذا الخيار مفيد في الحالات التي يمكن أن تفشل فيها التبعية مؤقتًا ولكننا لا نريد أن تتسبب هذه الإخفاقات المؤقتة في فشل الوحدات التابعة. لا تُشعر الوحدات التابعة بهذه الإخفاقات المؤقتة.

        أُضيف في الإصدار 254.

        • إذا ضُبط على debug، فسيقوم مدير الخدمة بتسجيل الرسائل المتعلقة بهذه الوحدة بمستوى التنقيح أثناء محاولة إعادات التشغيل الآلية، حتى تصل الخدمة إلى حد المعدل أو تنجح، وسيُضبط متغير البيئة $DEBUG_INVOCATION=1 للوحدة. هذا مفيد للحصول على معلومات إضافية عندما تفشل خدمة في بدء التشغيل، دون الحاجة إلى تمكين تسجيل مستوى التنقيح استباقيًا أو دائمًا في systemd، وهو أمر مسهب للغاية. هذا يكافئ وضع normal في الحالات الأخرى.

        أُضيف في الإصدار 257.

    أُضيف في الإصدار 254.

SuccessExitStatus=
    يأخذ قائمة بتعريفات حالة الخروج التي، عندما تُرجعها عملية الخدمة الرئيسة، ستُعتبر إنهاءً ناجحًا، بالإضافة إلى حالة الخروج الناجحة العادية 0 و، باستثناء Type=oneshot، الإشارات SIGHUP و SIGINT و SIGTERM و SIGPIPE. يمكن أن تكون تعريفات حالة الخروج عبارة عن حالات إنهاء عددية، أو أسماء حالات إنهاء، أو أسماء إشارات إنهاء، مفصولة بمسافات. انظر قسم رموز خروج العملية في systemd.exec(5) للحصول على قائمة بأسماء حالات الإنهاء (لهذا الإعداد يجب استخدام الجزء الذي لا يحتوي على البادئة "EXIT_" أو "EX_" فقط). انظر signal(7) للحصول على قائمة بأسماء الإشارات.

    لاحظ أن هذا الإعداد لا يغير الخريطة بين حالات الخروج الرقمية وأسمائها، أي بغض النظر عن كيفية استخدام هذا الإعداد، ستظل القيمة 0 تقابل "SUCCESS" (وبالتالي تظهر عادةً كـ "0/SUCCESS" في مخرجات الأدوات) والقيمة 1 تقابل "FAILURE" (وبالتالي تظهر عادةً كـ "1/FAILURE")، وهكذا. إنه يتحكم فقط فيما يحدث كتأثير لحالات الخروج هذه، وكيف ينتشر ذلك إلى حالة الخدمة ككل.

    قد يظهر هذا الخيار أكثر من مرة، وفي هذه الحالة تُدمج قائمة حالات الخروج الناجحة. إذا عُينت سلسلة فارغة لهذا الخيار، فستُعاد تهيئة القائمة، ولن يكون لجميع التعيينات السابقة لهذا الخيار أي تأثير.

    مثال 1. خدمة مع إعداد SuccessExitStatus=

        SuccessExitStatus=TEMPFAIL 250 SIGKILL

    تُعتبر حالة الخروج 75 (TEMPFAIL)، و 250، وإشارة الإنهاء SIGKILL إنهاءات خدمة نظيفة. ملاحظة: يمكن استخدام systemd-analyze exit-status لسرد حالات الخروج والترجمة بين قيم الحالة الرقمية والأسماء.

    أُضيف في الإصدارة 189.

RestartPreventExitStatus=
    يأخذ قائمة بتعريفات حالة الخروج التي، عندما تُرجعها عملية الخدمة الرئيسة، ستمنع إعادة تشغيل الخدمة آليًا، بغض النظر عن إعداد إعادة التشغيل المهيأ بواسطة Restart=. يمكن أن تكون تعريفات حالة الخروج عبارة عن حالات إنهاء عددية، أو أسماء حالات إنهاء، أو أسماء إشارات إنهاء، مفصولة بمسافات. القيمة المبدئية هي قائمة فارغة، بحيث لا يُستثنى أي وضع خروج مبدئيًا من منطق إعادة التشغيل المهيأ.

    قد يظهر هذا الخيار أكثر من مرة، وفي هذه الحالة تُدمج قائمة الحالات المانعة لإعادة التشغيل. إذا عُينت سلسلة فارغة لهذا الخيار، فستُعاد تهيئة القائمة ولن يكون لجميع التعيينات السابقة لهذا الخيار أي تأثير.

    لاحظ أن هذا الإعداد ليس له أي تأثير على العمليات المهيأة عبر ExecStartPre= أو ExecStartPost= أو ExecStop= أو ExecStopPost= أو ExecReload=، بل يؤثر فقط على عملية الخدمة الرئيسة، أي إما تلك المستدعاة بواسطة ExecStart= أو العملية الرئيسة المهيأة بطريقة أخرى (اعتمادًا على Type=، PIDFile=، ...).

    أُضيف في الإصدارة 189.

RestartForceExitStatus=
    يأخذ قائمة بتعريفات حالة الخروج التي، عندما تُرجعها عملية الخدمة الرئيسة، ستفرض إعادة تشغيل الخدمة آليًا، بغض النظر عن إعداد إعادة التشغيل المهيأ بواسطة Restart=. تنسيق المعطى مشابه لـ RestartPreventExitStatus=.

    لاحظ أنه بالنسبة لخدمات Type=oneshot، فإن حالة الخروج الناجحة ستمنعها من إعادة التشغيل الآلي، بغض النظر عما إذا كانت حالات الخروج المقابلة مدرجة في هذا الخيار أم لا.

    أُضيف في الإصدارة 215.

RootDirectoryStartOnly=
    يأخذ معطى منطقيًا. إذا كان صحيحًا (true)، فإن الدليل الجذري، كما هو مهيأ باستخدام خيار RootDirectory= (انظر systemd.exec(5) لمزيد من المعلومات)، يُطبق فقط على العملية التي بدأت بـ ExecStart=، وليس على أوامر ExecStartPre= و ExecStartPost= و ExecReload= و ExecReloadPost= و ExecStop= و ExecStopPost= الأخرى المتنوعة. إذا كان خاطئًا (false)، يُطبق الإعداد على جميع الأوامر المهيأة بنفس الطريقة. القيمة المبدئية هي false.

NonBlocking=
    يضبط علم O_NONBLOCK لجميع واصفات الملفات الممررة عبر التنشيط المستند إلى المقبس. إذا كان صحيحًا (true)، فإن جميع واصفات الملفات >= 3 (أي جميعها باستثناء stdin و stdout و stderr)، باستثناء تلك الممررة عبر منطق تخزين واصف الملفات (انظر FileDescriptorStoreMax= للتفاصيل)، سيُضبط لها علم O_NONBLOCK وبالتالي تكون في الوضع غير الحاصر. هذا الخيار مفيد فقط بالاقتران مع وحدة مقبس، كما هو موصوف في systemd.socket(5) وليس له أي تأثير على واصفات الملفات التي حُفظت سابقًا في مخزن واصف الملفات على سبيل المثال. القيمة المبدئية هي false.

    لاحظ أنه إذا هُيئت نفس وحدة المقبس لتُمَرر إلى وحدات خدمة متعددة (عبر إعداد Sockets=، انظر أدناه)، وكان لهذه الخدمات تهيئات NonBlocking= مختلفة، فإن الحالة الدقيقة لـ O_NONBLOCK تعتمد على الترتيب الذي تُستدعى به هذه الخدمات، وستتغير ربما بعد أن تستحوذ شيفرة الخدمة بالفعل على واصف ملف المقبس، ببساطة لأن حالة O_NONBLOCK للمقبس مشتركة بين جميع واصفات الملفات التي تشير إليه. وبالتالي، من الضروري أن تستخدم جميع الخدمات التي تشترك في نفس المقبس نفس تهيئة NonBlocking=، وألا تغير العلم في شيفرة الخدمة أيضًا.

NotifyAccess=
    يتحكم في الوصول إلى مقبس إشعارات حالة الخدمة، كما هو متاح عبر استدعاء sd_notify(3). يأخذ أحد الخيارات none (المبدئي) أو main أو exec أو all. إذا كان none، فلن تُقبل أي تحديثات لحالة العفريت من عمليات الخدمة، وتُتجاهل جميع رسائل تحديث الحالة. إذا كان main، تُقبل فقط تحديثات الخدمة المرسلة من العملية الرئيسة للخدمة. إذا كان exec، تُقبل فقط تحديثات الخدمة المرسلة من أي من العمليات الرئيسة أو عمليات التحكم الناشئة عن أحد أوامر Exec*=. إذا كان all، تُقبل جميع تحديثات الخدمات من جميع أعضاء مجموعة التحكم الخاصة بالخدمة. يجب ضبط هذا الخيار لفتح الوصول إلى مقبس الإشعارات عند استخدام Type=notify/Type=notify-reload أو WatchdogSec= (انظر أعلاه). إذا استُخدمت تلك الخيارات ولم يُهياً NotifyAccess=، فسيُضبط ضمنيًا على main.

    لاحظ أن إشعارات sd_notify() قد تُنسب إلى الوحدات بشكل صحيح فقط إذا كانت العملية المرسلة لا تزال موجودة في الوقت الذي تعالج فيه العملية ذات المعرف 1 (PID 1) الرسالة، أو إذا كانت العملية المرسلة مُتتبعة صراحةً في وقت التشغيل بواسطة مدير الخدمة. الحالة الأخيرة تكون عندما يفرع مدير الخدمة العملية في الأصل، أي في جميع العمليات التي تطابق main أو exec. بالمقابل، إذا أرسلت عملية مساعدة للوحدة رسالة sd_notify() وخرجت فورًا، فقد لا يتمكن مدير الخدمة من نسبة الرسالة بشكل صحيح إلى الوحدة، وبالتالي سيتجاهلها، حتى لو ضُبط NotifyAccess=all لها.

    وبالتالي، للتخلص من جميع شروط السباق التي تنطوي على البحث عن وحدة العميل ونسبة الإشعارات إلى الوحدات بشكل صحيح، يمكن استخدام sd_notify_barrier(). يعمل هذا الاستدعاء كنقطة تزامن ويضمن أن جميع الإشعارات المرسلة قبل هذا الاستدعاء قد التُقطت بواسطة مدير الخدمة عندما يعود بنجاح. يلزم استخدام sd_notify_barrier() للعملاء الذين لا يستدعيهم مدير الخدمة، وإلا فإن آلية التزامن هذه غير ضرورية لنسبة الإشعارات إلى الوحدة.

Sockets=
    يحدد اسم وحدات المقبس التي يجب أن ترث هذه الخدمة واصفات ملفات المقابس منها عند بدء تشغيل الخدمة. عادةً، لا ينبغي أن يكون من الضروري استخدام هذا الإعداد، لأن جميع واصفات ملفات المقابس التي تشترك وحدتها في نفس اسم الخدمة (مع مراعاة لاحقة اسم الوحدة المختلفة بالطبع) تُمرر إلى العملية الناتجة.

    لاحظ أن واصفات ملفات المقبس نفسها قد تُمرر إلى عمليات متعددة في وقت واحد. لاحظ أيضًا أنه قد تُنشط خدمة مختلفة عند حركة مرور المقبس الواردة عن تلك الخدمة المهيأة في النهاية لوراثة واصفات ملفات المقبس. أو بعبارة أخرى: إعداد Service= لوحدات .socket لا يجب أن يطابق عكس إعداد Sockets= لـ .service التي يشير إليها.

    قد يظهر هذا الخيار أكثر من مرة، وفي هذه الحالة تُدمج قائمة وحدات المقابس. لاحظ أنه بمجرد ضبطه، فإن مسح قائمة المقابس مرة أخرى (على سبيل المثال، عن طريق تعيين سلسلة فارغة لهذا الخيار) غير مدعوم.

FileDescriptorStoreMax=
    يضبط عدد واصفات الملفات التي يمكن تخزينها في مدير الخدمة للخدمة باستخدام رسائل "FDSTORE=1" الخاصة بـ sd_pid_notify_with_fds(3). هذا مفيد لتنفيذ الخدمات التي يمكنها إعادة التشغيل بعد طلب صريح أو انهيار دون فقدان الحالة. يمكن تخزين أي مقابس مفتوحة وواصفات ملفات أخرى لا ينبغي إغلاقها أثناء إعادة التشغيل بهذه الطريقة. يمكن تسلسل حالة التطبيق إما إلى ملف في RuntimeDirectory=، أو تخزينها في واصف ملف ذاكرة لـ memfd_create(2). القيمة المبدئية هي 0، أي لا يجوز تخزين واصفات ملفات في مدير الخدمة. تُمرر جميع واصفات الملفات الممررة إلى مدير الخدمة من خدمة معينة مرة أخرى إلى العملية الرئيسة للخدمة عند إعادة تشغيل الخدمة التالية (انظر sd_listen_fds(3) للحصول على تفاصيل حول البروتوكول الدقيق المستخدم والترتيب الذي تُمرر به واصفات الملفات). تُغلق أي واصفات ملفات ممررة إلى مدير الخدمة آليًا عند ظهور POLLHUP أو POLLERR عليها، أو عندما تتوقف الخدمة تمامًا ولا توجد وظيفة مجدولة أو قيد التنفيذ لها (يمكن تعديل الأخير باستخدام FileDescriptorStorePreserve=، انظر أدناه). إذا استُخدم هذا الخيار، فيجب ضبط NotifyAccess= (انظر أعلاه) لفتح الوصول إلى مقبس الإشعارات الذي يوفره systemd. إذا لم يُضبط NotifyAccess=، فسيُضبط ضمنيًا على main.

    يمكن استخدام أمر fdstore لـ systemd-analyze(1) لسرد المحتويات الحالية لمخزن واصف الملفات الخاص بالخدمة.

    لاحظ أن مدير الخدمة سيمرر فقط واصفات الملفات الموجودة في مخزن واصف الملفات إلى العمليات الخاصة بالخدمة نفسها، ولن يمررها أبدًا إلى عملاء آخرين عبر IPC أو ما شابه. ومع ذلك، فإنه يسمح للعملاء غير المتميزين بالاستعلام عن قائمة واصفات الملفات المفتوحة حالياً للخدمة. وبالتالي يمكن وضع البيانات الحساسة بأمان داخل الملفات المشار إليها، ولكن لا ينبغي إرفاقها بالبيانات الوصفية (مثل تضمينها في أسماء الملفات) لواصفات الملفات المخزنة.

    إذا ضُبط هذا الخيار على قيمة غير صفرية، فسيُضبط متغير البيئة $FDSTORE للعمليات المستدعاة لهذه الخدمة. انظر systemd.exec(5) للتفاصيل.

    لمزيد من المعلومات حول مخزن واصف الملفات، انظر نظرة عامة على مخزن واصف الملفات[1].

    أُضيف في الإصدارة 219.

FileDescriptorStorePreserve=
    يأخذ أحد الخيارات no أو yes أو restart ويتحكم في وقت تحرير مخزن واصف الملفات الخاص بالخدمة (أي وقت إغلاق واصفات الملفات الموجودة، إن وُجدت). إذا ضُبط على no، يُحرر مخزن واصف الملفات آليًا عند إيقاف الخدمة؛ وإذا ضُبط على restart (المبدئي)، فإنه يُحتفظ به طالما أن الوحدة ليست غير نشطة ولا فاشلة، أو أن هناك وظيفة مجدولة للخدمة، أو يُتوقع إعادة تشغيل الخدمة. إذا ضُبط على yes، يُحتفظ بمخزن واصف الملفات وتُعطل جمع المهملات للوحدة. الأمر الأخير مفيد لإبقاء المدخلات في مخزن واصف الملفات مثبتة حتى تُزال الوحدة، أو يخرج مدير الخدمة، أو تتلقى واصفات الملفات EPOLLHUP أو EPOLLERR.

    استخدم أمر systemctl clean --what=fdstore ... لتحرير مخزن واصف الملفات صراحةً.

    أُضيف في الإصدار 254.

USBFunctionDescriptors=
    يضبط موقع ملف يحتوي على واصفات USB FunctionFS[2]، لتنفيذ وظائف أداة USB. يُستخدم هذا فقط بالاقتران مع وحدة مقبس مهيأة باستخدام ListenUSBFunction=. تُكتب محتويات هذا الملف إلى ملف ep0 بعد فتحه.

    أُضيف في الإصدارة 227.

USBFunctionStrings=
    يضبط موقع ملف يحتوي على سلاسل نصوص USB FunctionFS. السلوك مشابه لـ USBFunctionDescriptors= أعلاه.

    أُضيف في الإصدارة 227.

OOMPolicy=
    اضبط سياسة قتل العمليات عند نقص الذاكرة (OOM) للنواة وقاتل OOM في مساحة المستخدم systemd-oomd.service(8). في لينكس، عندما تصبح الذاكرة نادرة لدرجة أن النواة تواجه صعوبة في تخصيص الذاكرة لنفسها، قد تقرر قتل عملية جارية لتوفير الذاكرة وتقليل ضغطها. لاحظ أن systemd-oomd.service حل أكثر مرونة يهدف لمنع حالات نقص الذاكرة لمساحة المستخدم أيضًا، وليس النواة فقط، عبر محاولة إنهاء الخدمات مبكرًا، قبل أن تضطر النواة للتصرف.

    يأخذ هذا الإعداد أحد الخيارات continue أو stop أو kill. إذا ضُبط على continue وقُتلت عملية في الوحدة بواسطة قاتل نفاد الذاكرة (OOM killer)، يُسجل هذا في السجل ولكن تستمر الوحدة في العمل. إذا ضُبط على stop، يُسجل الحدث وتُنهى عمليات الوحدة نظيفًا بواسطة مدير الخدمة. إذا ضُبط على kill وقُتلت إحدى عمليات الوحدة بواسطة قاتل نفاد الذاكرة، تُوجَّه النواة لقتل جميع العمليات المتبقية للوحدة أيضًا، عن طريق ضبط السمة memory.oom.group على القيمة 1؛ انظر أيضًا صفحة النواة مجموعة التحكم الإصدار الثاني Control Group v2[3]. في حالة كل من stop و kill، تنتهي الخدمة في النهاية في حالة الفشل oom-kill وبعد ذلك قد يُطبق الإعداد Restart=.

    يُضبط مبدئياً على الإعداد DefaultOOMPolicy= في systemd-system.conf(5)، باستثناء الوحدات التي يكون فيها Delegate= مفعلاً، حيث يكون الإجراء المبدئي هو الاستمرار continue.

    استخدم إعداد OOMScoreAdjust= لضبط ما إذا كانت عمليات الوحدة ستُعتبر مرشحة مفضلة أو أقل تفضيلًا للإنهاء بواسطة منطق قاتل OOM في لينكس. انظر systemd.exec(5) للتفاصيل.

    ينطبق هذا الإعداد أيضًا على systemd-oomd.service(8). وبشكل مشابه لعمليات إنهاء OOM التي تنفذها النواة، يحدد هذا الإعداد حالة الوحدة بعد أن ينهي systemd-oomd مجموعة cgroup المرتبطة بها.

    أُضيف في الإصدار 243.

OpenFile=
    يأخذ وسيطًا على الصيغة "path[:fd-name:options]"، حيث:

        • "path" هو مسار إلى ملف أو مقبس AF_UNIX في نظام ملفات؛

        • "fd-name" هو اسم سيرتبط بواصف الملف؛ يمكن أن يحتوي الاسم على أي محرف ASCII، ولكن يجب أن يستبعد محارف التحكم والرمز ":"، ويجب ألا يتجاوز طوله 255 محرفًا؛ وهو اختياري، وإذا لم يُوفّر، فإنه يؤول مبدئيًا إلى اسم الملف؛

        • "options" هي قائمة مفصولة بفاصلة لخيارات الوصول؛ القيم الممكنة هي "read-only"، و"append"، و"truncate"، و"graceful"؛ وإذا لم تُحدّد، ستُفتح الملفات في وضع rw؛ وإذا حُدّد الخيار "graceful"، تُتجاهل الأخطاء أثناء فتح الملف/المقبس. يُعامل تحديد الخيار نفسه عدة مرات على أنه خطأ.

    يُفتح الملف أو المقبس بواسطة مدير الخدمة ويُمرّر واصف الملف إلى الخدمة. إذا كان المسار مقبسًا، فإننا نستدعي connect() عليه. انظر sd_listen_fds(3) لمزيد من التفاصيل حول كيفية استرداد واصفات الملفات هذه.

    هذا الضبط مفيد للسماح للخدمات بالوصول إلى الملفات/المقابس التي لا يمكنها الوصول إليها بنفسها (بسبب تشغيلها في مساحة أسماء وصل منفصلة، أو عدم امتلاكها للامتيازات، ...).

    يمكن تحديد هذا الضبط عدة مرات، وفي هذه الحالة تُفتح جميع المسارات المحددة وتُمرّر واصفات الملفات إلى الخدمة. إذا عُيّنت سلسلة نصية فارغة، تُصفّر قائمة الملفات المفتوحة الكاملة المعرّفة قبل هذا.

    أُضيف في الإصدار 253.

ReloadSignal=
    يضبط إشارة عملية UNIX لإرسالها إلى عملية الخدمة الرئيسة عند طلب إعادة تحميل تهيئة الخدمة. يؤول مبدئيًا إلى SIGHUP. ليس لهذا الخيار أي تأثير إلا إذا استُخدم Type=notify-reload، انظر أعلاه.

    أُضيف في الإصدار 253.

RefreshOnReload=
    يأخذ وسيطًا منطقيًا، أو قائمة بالموارد المعرّفة في systemd.exec(5). القيم الممكنة هي extensions و credentials، يفصل بينها مسافة. بادئة القائمة بمحرف تِلْدة واحد ("~") تعكس التأثير. يؤول مبدئيًا إلى extensions. التعيين الفارغ يُصفّر القائمة إلى الوضع المبدئي. إذا فُعّل، فإن الموارد المقابلة (ExtensionImages=/ExtensionDirectories= لـ extensions و LoadCredential=/ImportCredential=/ SetCredential= (إلى جانب نظائرها Encrypted) لـ credentials) ستُنعش عند إعادة تحميل الخدمة. إذا كانت القيمة yes، فإن جميع الموارد المدرجة أعلاه والتي تستخدمها الخدمة تُنعش.

    على وجه الخصوص، إذا ضُبط هذا الخيار صراحةً، وكانت الموارد المعنية قيد الاستخدام، فقد تُعاد تحميل الخدمة دون أي آلية إعادة تحميل فعلية (ExecReload= أو Type=notify-reload) لإخطار العملية الرئيسة، وفي هذه الحالة تُعتبر إعادة التحميل مكتملة فورًا بعد الإنعاش.

    أُضيف في الإصدار 260.

تحقق من systemd.unit(5)، و systemd.exec(5)، و systemd.kill(5) لمزيد من الإعدادات.

سطور الأوامر

يصف هذا القسم تحليل سطر الأوامر واستبدالات المتغيرات والمحددات لخيارات ExecStart=، و ExecStartPre=، و ExecStartPost=، و ExecReload=، و ExecStop=، و ExecStopPost=، و ExecCondition=.

يمكن تحديد سطور أوامر متعددة باستخدام الضبط ذي الصلة عدة مرات.

تُزال علامات الاقتباس من كل سطر أوامر باستخدام القواعد الموصوفة في قسم "Quoting" في systemd.syntax(7). يصبح العنصر الأول هو الأمر المراد تنفيذه، والعناصر اللاحقة هي الوسائط.

هذه الصيغة مستوحاة من صيغة الصدفة، ولكن لا تُفهم سوى المحارف الفوقية والتوسيعات الموصوفة في الفقرات التالية، وتوسيع المتغيرات مختلف. على وجه التحديد، إعادة التوجيه باستخدام "<" و "<<" و ">" و ">>"، والأنابيب باستخدام "|"، وتشغيل البرامج في الخلفية باستخدام "&"، والعناصر الأخرى لصيغة الصدفة غير مدعومة.

يمكن أن يحتوي الأمر المراد تنفيذه على مسافات، ولكن محارف التحكم غير مسموح بها.

يمكن أن يُسبق كل أمر بعدد من المحارف الخاصة:

الجدول 2. بادئات الملفات التنفيذية الخاصة
البادئة | التأثير
"@" | إذا سُبق مسار الملف التنفيذي بـ "@"، فستُمرّر العلامة الثانية المحددة كـ argv[0] إلى العملية المنفّذة (بدلاً من اسم الملف الفعلي)، متبوعة بالوسائط الإضافية المحددة، ما لم يُحدّد "|" أيضًا، وفي هذه الحالة يُمكّن دلالات صدفة الولوج للصدفة المولّدة عن طريق إلحاق بادئة "-" بـ argv[0].
"-" | إذا سُبق مسار الملف التنفيذي بـ "-"، فإن رمز خروج الأمر الذي يُعتبر عادةً فشلاً (أي حالة خروج غير صفرية أو خروج غير طبيعي بسبب إشارة) يُسجّل، ولكن ليس له تأثير آخر ويُعتبر مكافئًا للنجاح.
":" | إذا سُبق مسار الملف التنفيذي بـ ":"، فلن يُطبّق استبدال متغير البيئة (كما هو موصوف أسفل هذا الجدول).
"+" | إذا سُبق مسار الملف التنفيذي بـ "+" فستُنفّذ العملية بامتيازات كاملة. في هذا الوضع، لا تُطبّق قيود الامتيازات المضبوطة بـ User= أو Group= أو CapabilityBoundingSet= أو خيارات مساحات أسماء نظام الملفات المختلفة (مثل PrivateDevices= و PrivateTmp=) على سطر الأوامر المستدعى (ولكنها لا تزال تؤثر على أي سطور ExecStart= و ExecStop= و ... أخرى). ومع ذلك، لاحظ أن هذا لن يتجاوز الخيارات التي تنطبق على مجموعة التحكم بأكملها، مثل DevicePolicy=، انظر systemd.resource-control(5) للقائمة الكاملة.
"!" | على غرار المحرف "+" المناقش أعلاه، يتيح هذا استدعاء سطور الأوامر بامتيازات مرتفعة. ومع ذلك، على عكس "+"، فإن المحرف "!" يغير حصريًا تأثير User= و Group= و SupplementaryGroups=، أي المقاطع التي تؤثر على اعتمادات المستخدم والمجموعة فقط. لاحظ أنه يمكن دمج هذا الضبط مع DynamicUser=، وفي هذه الحالة يُخصّص زوج مستخدم/مجموعة ديناميكي قبل استدعاء الأمر، ولكن يُترك تغيير الاعتمادات للعملية المنفّذة نفسها.
"|" | إذا حُدّد "|" كمستقل كمسار للملف التنفيذي، فاستدعِ صدفة User= المبدئية. وإذا حُدّد كبادئة، فاستخدم الصدفة ("-c") لتوليد الملف التنفيذي. وعند استخدام "@" بالتزامن مع ذلك، ستُلحق بادئة "-" بـ argv[0] للصدفة لتمكين دلالات صدفة الولوج.

يمكن استخدام "@" و "|" و "-" و ":" وأحد الخيارين "+"/"!" معًا ويمكن أن تظهر بأي ترتيب. ومع ذلك، لا يمكن تحديد "+" و "!" في الوقت نفسه.

لكل أمر، يجب أن يكون الوسيط الأول إما مسارًا مطلقًا لملف تنفيذي أو اسم ملف بسيط دون أي شرطات مائلة. إذا لم يكن الأمر مسارًا كاملاً (مطلقًا)، فسيُحلّ إلى مسار كامل باستخدام مسار بحث ثابت يُحدّد في وقت التصريف. تشمل الأدلة المبحوث فيها /usr/local/bin/ و /usr/bin/ ونظائرها sbin/ (فقط في الأنظمة التي تستخدم bin/ و sbin/ منفصلين). وبالتالي من الآمن استخدام اسم الملف التنفيذي فقط في حالة الملفات التنفيذية الموجودة في أي من الأدلة "القياسية"، ويجب استخدام مسار مطلق في الحالات الأخرى. تلميح: يمكن الاستعلام عن مسار البحث هذا باستخدام systemd-path search-binaries-default.

يقبل سطر الأوامر محددات "%" كما هو موصوف في systemd.unit(5).

الوسيط الذي يتكون فقط من ";" يجب هروبه، أي يُحدّد كـ "\;".

استبدال متغيرات البيئة الأساسية مدعوم. استخدم "${FOO}" كجزء من كلمة، أو ككلمة قائمة بذاتها، على سطر الأوامر، وفي هذه الحالة ستُمحى وتُستبدل بالقيمة الدقيقة لمتغير البيئة (إن وُجد) بما في ذلك جميع المساحات البيضاء التي تحتوي عليها، مما يؤدي دائمًا إلى وسيط واحد تمامًا. استخدم "$FOO" ككلمة منفصلة على سطر الأوامر، وفي هذه الحالة ستُستبدل بقيمة متغير البيئة مقسومة عند المساحة البيضاء، مما يؤدي إلى صفر أو أكثر من الوسائط. لهذا النوع من التوسيع، تُحترم علامات الاقتباس عند التقسيم إلى كلمات، وتُزال بعد ذلك.

مثال:

    Environment="ONE=one" 'TWO=two two'
    ExecStart=echo $ONE $TWO ${TWO}

سيؤدي هذا إلى تنفيذ /bin/echo بأربعة وسائط: "one" و "two" و "two" و "two two".

مثال:

    Environment=ONE='one' "TWO='two two' too" THREE=
    ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}
    ExecStart=/bin/echo $ONE $TWO $THREE

ينتج عن هذا استدعاء /bin/echo مرتين، المرة الأولى بوسائط "'one'" و "'two two' too" و ""، والمرة الثانية بوسائط "one" و "two two" و "too".

ما لم تكن الأوامر ذات بادئة الملف التنفيذي الخاصة ":"، لتمرير علامة دولار حرفية، استخدم "$$". تُعامل المتغيرات التي لا تُعرف قيمتها في وقت التوسيع كسلاسل نصية فارغة. لاحظ أن الوسيط الأول (أي البرنامج المراد تنفيذه) لا يمكن أن يكون متغيرًا.

يمكن تعريف المتغيرات المراد استخدامها بهذا الأسلوب من خلال Environment= و EnvironmentFile=. بالإضافة إلى ذلك، يمكن استخدام المتغيرات المدرجة في قسم "Environment variables in spawned processes" في systemd.exec(5)، والتي تُعتبر "تهيئة استاتيكية" (وهذا يشمل على سبيل المثال $USER، ولكن ليس $TERM).

لاحظ أن سطور أوامر الصدفة غير مدعومة مباشرة، و "|" يستدعي صدفة المستخدم المبدئية وهي غير حتمية. يُوصى بتحديد تطبيق صدفة صراحةً إذا كانت القابلية للنقل مرغوبة. مثال:

    ExecStart=sh -c 'dmesg | tac'

مثال:

    ExecStart=echo one
    ExecStart=echo "two two"

سيؤدي هذا إلى تنفيذ echo مرتين، في كل مرة بوسيط واحد: "one" و "two two" على التوالي. نظرًا لتحديد أمرين، يجب استخدام Type=oneshot.

مثال:

    Type=oneshot
    ExecStart=:echo $USER
    ExecStart=-false
    ExecStart=+:@true $TEST

سيؤدي هذا إلى تنفيذ /usr/bin/echo بالوسيط الحرفي "$USER" (":" يمنع توسيع المتغير)، ثم /usr/bin/false (ستُتجاهل القيمة المعادة لأن "-" يمنع التحقق من القيمة المعادة)، و /usr/bin/true (بامتيازات مرتفعة، مع "$TEST" كـ argv[0]).

مثال:

    ExecStart=echo / >/dev/null & \; \
    ls

سيؤدي هذا إلى تنفيذ echo بخمسة وسائط: "/" و ">/dev/null" و "&" و ";" و "ls".

أمثلة

المثال 3. خدمة بسيطة

ينشئ ملف الوحدة التالي خدمة ستنفذ /usr/sbin/foo-daemon. نظرًا لعدم تحديد أي Type=، سيُفترض الوضع المبدئي Type=simple. سيفترض systemd أن الوحدة قد بُدئت فورًا بعد أن يبدأ البرنامج في التنفيذ.

    [Unit]
    Description=Foo
    [Service]
    ExecStart=/usr/sbin/foo-daemon
    [Install]
    WantedBy=multi-user.target

لاحظ أن systemd يفترض هنا أن العملية التي بدأها systemd ستستمر في العمل حتى تنتهي الخدمة. إذا قام البرنامج بجدولة نفسه في الخلفية (أي يتفرع)، فيرجى استخدام Type=forking بدلاً من ذلك.

نظرًا لعدم تحديد أي ExecStop=، سيرسل systemd إشارة SIGTERM إلى جميع العمليات التي بدأت من هذه الخدمة، وبعد مهلة زمنية سيرسل أيضًا SIGKILL. يمكن تعديل هذا السلوك، انظر systemd.kill(5) للتفاصيل.

لاحظ أن نوع الوحدة هذا لا يتضمن أي نوع من الإشعارات عندما تكمل الخدمة تهيئتها. لهذا، يجب استخدام أنواع وحدات أخرى، مثل Type=notify/Type=notify-reload إذا كانت الخدمة تفهم بروتوكول إشعارات systemd، أو Type=forking إذا كانت الخدمة يمكنها وضع نفسها في الخلفية أو Type=dbus إذا حصلت الوحدة على اسم DBus بمجرد اكتمال التهيئة. انظر أدناه.

المثال 4. خدمة ذات طلقة واحدة

في بعض الأحيان، ينبغي للوحدات مجرد تنفيذ إجراء دون الإبقاء على عمليات نشطة، مثل فحص نظام ملفات أو إجراء تنظيف عند الإقلاع. لهذا الغرض، يوجد الخيار Type=oneshot. ستنتظر الوحدات من هذا النوع حتى تنتهي العملية المحددة ثم تعود لتصبح غير نشطة. ستقوم الوحدة التالية بإجراء تنظيف:

    [Unit]
    Description=Cleanup old Foo data
    [Service]
    Type=oneshot
    ExecStart=/usr/sbin/foo-cleanup
    [Install]
    WantedBy=multi-user.target

لاحظ أن systemd سيعتبر الوحدة في حالة "بدء التشغيل" حتى ينتهي البرنامج، لذا ستنتظر الاعتماديات المرتبة انتهاء البرنامج قبل أن تبدأ هي نفسها. ستعود الوحدة إلى الحالة "غير نشطة" بعد الانتهاء من التنفيذ، دون أن تصل أبدًا إلى الحالة "نشطة". وهذا يعني أن طلبًا آخر لبدء الوحدة سيؤدي إلى تنفيذ الإجراء مجددًا.

وحدات الخدمة من النوع Type=oneshot هي وحدات الخدمة الوحيدة التي يمكن أن يُحدد لها أكثر من ExecStart= واحد. بالنسبة للوحدات ذات الأوامر المتعددة (Type=oneshot)، ستُشغل جميع الأوامر مجددًا.

بالنسبة لـ Type=oneshot، فإن Restart=always و Restart=on-success غير مسموح بهما.

المثال 5. خدمة ذات طلقة واحدة قابلة للإيقاف

على غرار خدمات الطلقة الواحدة، توجد أحيانًا وحدات تحتاج إلى تنفيذ برنامج لإعداد شيء ما ثم تنفيذ برنامج آخر لإغلاقه، ولكن لا تظل أي عملية نشطة بينما تُعتبر "مبدوءة". يمكن أن يقع ضبط الشبكة أحيانًا في هذه الفئة. حالة استخدام أخرى هي إذا كان ينبغي عدم تنفيذ خدمة طلقة واحدة في كل مرة تُسحب فيها كاعتمادية، بل في المرة الأولى فقط.

لهذا، يعرف systemd الضبط RemainAfterExit=yes، والذي يجعل systemd يعتبر الوحدة نشطة إذا خرج إجراء البدء بنجاح. يمكن استخدام هذا التوجيه مع جميع الأنواع، ولكنه أكثر فائدة مع Type=oneshot و Type=simple. مع Type=oneshot، ينتظر systemd حتى يكتمل إجراء البدء قبل أن يعتبر الوحدة نشطة، لذا لا تبدأ الاعتماديات إلا بعد نجاح إجراء البدء. مع Type=simple، ستبدأ الاعتماديات فورًا بعد إرسال إجراء البدء. توفر الوحدة التالية مثالاً لجدار حماية استاتيكي بسيط.

    [Unit]
    Description=Simple firewall
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/local/sbin/simple-firewall-start
    ExecStop=/usr/local/sbin/simple-firewall-stop
    [Install]
    WantedBy=multi-user.target

بما أن الوحدة تُعتبر تعمل بعد خروج إجراء البدء، فإن استدعاء systemctl start على تلك الوحدة مجددًا لن يؤدي إلى اتخاذ أي إجراء.

المثال 6. الخدمات المتفرعة التقليدية

تقوم العديد من العفاريت/الخدمات التقليدية بوضع نفسها في الخلفية (أي تتفرع) عند بدء التشغيل. اضبط Type=forking في ملف وحدة الخدمة لدعم وضع التشغيل هذا. سيعتبر systemd الخدمة في مرحلة التهيئة طالما أن البرنامج الأصلي لا يزال يعمل. بمجرد خروجه بنجاح وبقاء عملية واحدة على الأقل (وكون RemainAfterExit=no)، تُعتبر الخدمة مبدؤة.

غالبًا ما يتكون العفريت التقليدي من عملية واحدة فقط. لذلك، إذا تبقت عملية واحدة فقط بعد انتهاء العملية الأصلية، سيعتبر systemd تلك العملية هي العملية الرئيسة للخدمة. وفي هذه الحالة، سيكون المتغير $MAINPID متاحًا في ExecReload= و ExecStop=، إلخ.

في حال تبقي أكثر من عملية واحدة، سيكون systemd غير قادر على تحديد العملية الرئيسة، لذا لن يفترض وجود واحدة. وفي هذه الحالة، لن يتوسع $MAINPID إلى أي شيء. ومع ذلك، إذا قررت العملية كتابة ملف PID تقليدي، فسيكون systemd قادرًا على قراءة معرف العملية (PID) الرئيس من هناك. يرجى ضبط PIDFile= وفقًا لذلك. لاحظ أنه يجب على العفريت كتابة هذا الملف قبل الانتهاء من تهيئته. وإلا، فقد يحاول systemd قراءة الملف قبل وجوده.

يظهر المثال التالي عفريتًا بسيطًا يتفرع ويبدأ عملية واحدة فقط في الخلفية:

    [Unit]
    Description=My Simple Daemon
    [Service]
    Type=forking
    ExecStart=/usr/sbin/my-simple-daemon -d
    [Install]
    WantedBy=multi-user.target

يرجى الاطلاع على systemd.kill(5) للحصول على تفاصيل حول كيفية التأثير على الطريقة التي ينهي بها systemd الخدمة.

المثال 7. خدمات DBus

بالنسبة للخدمات التي تكتسب اسمًا على ناقل نظام DBus، استخدم Type=dbus واضبط BusName= وفقًا لذلك. لا ينبغي للخدمة أن تتفرع (تتحول لعفريت). سيعتبر systemd الخدمة مهيأة بمجرد اكتساب الاسم على ناقل النظام. يظهر المثال التالي خدمة DBus نموذجية:

    [Unit]
    Description=Simple DBus Service
    [Service]
    Type=dbus
    BusName=org.example.simple-dbus-service
    ExecStart=/usr/sbin/simple-dbus-service
    [Install]
    WantedBy=multi-user.target

بالنسبة للخدمات القابلة للتنشيط عبر الناقل (bus-activatable)، لا تدرج قسم [Install] في ملف خدمة systemd، بل استخدم خيار SystemdService= في ملف خدمة DBus المقابل، على سبيل المثال (/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service):

    [D-BUS Service]
    Name=org.example.simple-dbus-service
    Exec=/usr/sbin/simple-dbus-service
    User=root
    SystemdService=simple-dbus-service.service

يرجى الاطلاع على systemd.kill(5) للحصول على تفاصيل حول كيفية التأثير على الطريقة التي ينهي بها systemd الخدمة.

المثال 8. الخدمات التي تخطر systemd بتهيئتها

خدمات النوع Type=simple سهلة الكتابة حقًا، ولكن عيبها الرئيس هو عدم قدرة systemd على معرفة متى تكتمل تهيئة الخدمة المحددة. لهذا السبب، يدعم systemd بروتوكول إشعارات بسيطًا يسمح للعفاريت بجعل systemd على دراية بأنها انتهت من التهيئة. استخدم Type=notify أو Type=notify-reload لهذا الغرض. سيبدو ملف الخدمة النموذجي لمثل هذا العفريت كما يلي:

    [Unit]
    Description=Simple Notifying Service
    [Service]
    Type=notify-reload
    ExecStart=/usr/sbin/simple-notifying-service
    [Install]
    WantedBy=multi-user.target

لاحظ أنه يجب على العفريت دعم بروتوكول إشعارات systemd، وإلا فسيظن systemd أن الخدمة لم تبدأ بعد ويقتلها بعد مهلة زمنية. للحصول على مثال لكيفية تحديث العفاريت لدعم هذا البروتوكول بشكل شفاف، ألقِ نظرة على sd_notify(3). سيعتبر systemd الوحدة في حالة 'بدء التشغيل' حتى يصل إشعار الجاهزية.

يرجى الاطلاع على systemd.kill(5) للحصول على تفاصيل حول كيفية التأثير على الطريقة التي ينهي بها systemd الخدمة.

لتجنب تكرار الكود، يفضل استخدام sd_notify(3) عندما يكون ذلك ممكنًا، خاصة عند استخدام واجهات برمجة التطبيقات الأخرى التي يوفرها libsystemd(3) أيضًا، ولكن لاحظ أن بروتوكول الإشعارات بسيط للغاية ومضمون الاستقرار وفقًا لـ Interface Portability and Stability Promise[4]، لذا يمكن إعادة تطبيقه بواسطة الخدمات دون أي اعتماديات خارجية. للحصول على مثال مكتفٍ بذاته، انظر sd_notify(3).

انظر أيضًا

systemd(1), systemctl(1), systemd-system.conf(5), systemd.unit(5), systemd.exec(5), systemd.resource-control(5), systemd.kill(5), systemd.directives(7), systemd-run(1)

ملاحظات

1.  مخزن واصف الملف
    https://systemd.io/FILE_DESCRIPTOR_STORE

2.  نظام ملفات وظائف USB (USB FunctionFS)
    https://docs.kernel.org/usb/functionfs.html

3.  مجموعة التحكم النسخة 2
    https://docs.kernel.org/admin-guide/cgroup-v2.html

4.  وعد استقرار وقابلية نقل الواجهة
    https://systemd.io/PORTABILITY_AND_STABILITY/

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.