SYSTEMD-NOTIFY(1) systemd-notify SYSTEMD-NOTIFY(1)

systemd-notify - اطلاع‌رسانی به مدیر سرویس درباره تکمیل راه‌اندازی و سایر تغییرات وضعیت دیمن

systemd-notify [OPTIONS...] [VARIABLE=VALUE...]

systemd-notify --exec [OPTIONS...] [VARIABLE=VALUE...] ; -- {CMDLINE...}

systemd-notify --fork [OPTIONS...] -- {CMDLINE...}

systemd-notify می‌تواند توسط اسکریپت‌های سرویس فراخوانی شود تا تغییرات وضعیت را به مدیر سرویس فراخواننده اطلاع دهد. این ابزار می‌تواند برای ارسال اطلاعات دلخواه، کدگذاری‌شده در قالبی شبیه به فهرست رشته‌های بلوک متغیرهای محیطی، استفاده شود. مهم‌تر از همه، می‌توان از آن برای اعلان تکمیل راه‌اندازی استفاده کرد.

این ابزار در واقع عمدتاً یک پوسته (wrapper) پیرامون sd_notify() است و این قابلیت را در دسترس اسکریپت‌های پوسته قرار می‌دهد. برای جزئیات sd_notify(3) را ببینید.

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

توجه داشته باشید که سیستم‌دی از پذیرش به‌روزرسانی‌های وضعیت از این دستور خودداری خواهد کرد مگر اینکه NotifyAccess= به‌طور مناسب برای واحد سرویسی که این دستور از آن فراخوانی می‌شود تنظیم شده باشد. برای جزئیات systemd.service(5) را ببینید.

توجه داشته باشید که اعلان‌های sd_notify() تنها در صورتی می‌توانند به درستی به واحدها منتسب شوند که فرآیند ارسال‌کننده در زمان پردازش پیام توسط مدیر سرویس هنوز فعال باشد، یا اینکه فرآیند ارسال‌کننده صراحتاً در زمان اجرا توسط مدیر سرویس ردیابی شود. حالت دوم زمانی رخ می‌دهد که مدیر سرویس در ابتدا فرآیند را منشعب (fork) کرده باشد، یعنی در تمام فرآیندهایی که با NotifyAccess=main یا NotifyAccess=exec مطابقت دارند. برعکس، اگر یک فرآیند کمکیِ واحد پیامی از طریق sd_notify() ارسال کند و بلافاصله خارج شود، مدیر سرویس ممکن است نتواند پیام را به درستی به آن واحد منتسب کند و بنابراین آن را نادیده خواهد گرفت، حتی اگر NotifyAccess=all برای آن تنظیم شده باشد. برای رفع این مشکل، systemd-notify تا زمانی که پیام اعلان توسط مدیر سرویس پردازش شود منتظر خواهد ماند. هنگامی که --no-block استفاده شود، این همگام‌سازی برای دریافت اعلان‌ها غیرفعال می‌گردد و از این رو ممکن است شرایط رقابتی (race condition) یادشده رخ دهد، در صورتی که فرآیند فراخواننده، خودِ مدیر سرویس نبوده یا توسط مدیر سرویس ایجاد نشده باشد.

systemd-notify ابتدا تلاش خواهد کرد تا با وانمود کردن به داشتن PID فرآیند والدِ systemd-notify (یعنی فرآیند فراخواننده)، sd_notify() را فراخوانی کند. این کار تنها زمانی موفقیت‌آمیز خواهد بود که با دسترسی‌ها و اختیارات کافی فراخوانی شده باشد. در صورت عدم موفقیت، سپس به فراخوانی آن با PID خود بازمی‌گردد. این رفتار از این جهت مفید است که وقتی این ابزار از یک اسکریپت پوسته فراخوانی می‌شود، فرآیند پوسته — و نه فرآیند systemd-notify — به عنوان فرستنده پیام ظاهر می‌شود؛ که این به نوبه خود، به دلیل محدودیت‌های NotifyAccess=all، در صورتی که فرآیند پوسته فرآیند اصلی یک سرویس باشد، مفید خواهد بود. از سوییچ --pid= برای دستکاری این رفتار استفاده کنید.

گزینه‌های زیر پشتیبانی می‌شوند:

--ready

مدیر سرویس فراخواننده را از تکمیل راه‌اندازی سرویس یا بارگذاری مجدد پیکربندی مطلع می‌کند. این معادل systemd-notify READY=1 است. برای جزئیات درباره مفاهیم معنایی این گزینه، sd_notify(3) را ببینید.

--reloading

مدیر سرویس فراخواننده را از آغاز چرخه بارگذاری مجدد پیکربندی مطلع می‌کند. این معادل systemd-notify RELOADING=1 است (اما به صورت ضمنی فیلد MONOTONIC_USEC= را نیز همان‌طور که برای سرویس‌های Type=notify-reload لازم است تنظیم می‌کند؛ برای جزئیات systemd.service(5) را ببینید). برای جزئیات درباره مفاهیم معنایی این گزینه، sd_notify(3) را ببینید.

افزوده شده در نسخه 253.

--stopping

مدیر سرویس فراخواننده را از آغاز مرحله خاموش‌شدن (shutdown) سرویس مطلع می‌کند. این معادل systemd-notify STOPPING=1 است. برای جزئیات درباره مفاهیم معنایی این گزینه، sd_notify(3) را ببینید.

افزوده شده در نسخه 253.

--pid=

مدیر سرویس را از PID اصلی سرویس مطلع می‌کند. یک PID را به عنوان آرگومان دریافت می‌کند. اگر آرگومان به صورت "auto" مشخص شود یا حذف گردد، از PID فرآیندی که systemd-notify را فراخوانی کرده استفاده می‌شود، مگر اینکه آن فرآیند مدیر سرویس باشد. اگر آرگومان به صورت "self" مشخص شود، از PID خودِ دستور systemd-notify استفاده می‌شود، و اگر "parent" مشخص شود، از PID فرآیند فراخواننده استفاده می‌شود — حتی اگر مدیر سرویس باشد. --pid=auto معادل systemd-notify --pid=$PID است. برای جزئیات درباره مفاهیم معنایی این گزینه، sd_notify(3) را ببینید.

systemd-notify ابتدا تلاش خواهد کرد تا با وانمود کردن به داشتن PID مشخص‌شده با --pid=، sd_notify() را فراخوانی کند. این کار تنها در صورتی موفقیت‌آمیز خواهد بود که با اختیارات کافی فراخوانی شده باشد. در صورت عدم موفقیت، سپس به فراخوانی آن با PID خود بازمی‌گردد. در عمل، این بدان معناست که یک فراخوانی ممتاز از systemd-notify --pid= ممکن است محدودیت‌های اعمال‌شده NotifyAccess=main یا NotifyAccess=exec برای یک سرویس را دور بزند.

اگر این سوییچ در یک فراخوانی بدون اختیارات ممتاز از systemd-notify توسط فرآیندی استفاده شود که قرار است فرآیند اصلی جدید یک سرویس باشد — و آن فرآیند توسط مدیر سرویس منشعب نشده باشد (یا فرآیند اصلی فعلی نباشد) —، در این صورت ضروری است که NotifyAccess=all در فایل واحد سرویس تنظیم شود، در غیر این صورت به دلایل امنیتی اعلان نادیده گرفته خواهد شد. برای جزئیات systemd.service(5) را ببینید.

--uid=USER

شناسه کاربر (UID) را برای ارسال اعلان از طرف آن تنظیم می‌کند. یک نام کاربری یونیکس یا UID عددی را دریافت می‌کند. در صورت تعیین، پیام اعلان با UID مشخص‌شده به عنوان فرستنده ارسال خواهد شد، به جای کاربری که دستور تحت آن فراخوانی شده است. این گزینه برای اینکه بتواند هویت کاربری فرآیند را دستکاری کند به اختیارات کافی نیاز دارد.

افزوده شده در نسخه 237.

--status=

یک رشته وضعیت آزاد و خوانا برای انسان برای دیمن به مدیر سرویس ارسال می‌کند. این گزینه رشته وضعیت را به عنوان آرگومان دریافت می‌کند. این معادل systemd-notify STATUS=... است. برای جزئیات درباره مفاهیم معنایی این گزینه، sd_notify(3) را ببینید. این اطلاعات علاوه بر سایر مکان‌ها، در خروجی status دستور systemctl(1)' نیز نمایش داده می‌شود.

--booted

اگر سیستم با سیستم‌دی راه‌اندازی (boot) شده باشد مقدار 0 و در غیر این صورت مقداری غیر صفر برمی‌گرداند. اگر این گزینه ارسال شود، هیچ پیامی ارسال نخواهد شد. بنابراین این گزینه ارتباطی با گزینه‌های دیگر ندارد. برای جزئیات درباره مفاهیم معنایی این گزینه، sd_booted(3) را ببینید. یک روش جایگزین برای بررسی این وضعیت، فراخوانی systemctl(1) با دستور is-system-running است. اگر سیستم با سیستم‌دی بوت نشده باشد، خروجی آن "offline" خواهد بود، هرچند مقدار بازگشتی معنای متفاوتی دارد.

--no-block

به‌طور همگام منتظر پایان عملیات درخواست‌شده نمی‌ماند. استفاده از این گزینه تنها زمانی توصیه می‌شود که systemd-notify توسط مدیر سرویس ایجاد شده باشد، یا زمانی که فرآیند فراخواننده مستقیماً توسط مدیر سرویس ایجاد شده و دسترسی‌های کافی داشته باشد تا به systemd-notify اجازه دهد از طرف آن اعلان را ارسال کند. ارسال اعلان‌ها با تنظیم این گزینه در سایر موارد مستعد شرایط رقابتی (race conditions) است.

افزوده شده در نسخه 246.

--exec

در صورت تعیین، systemd-notify پس از تکمیل عملیات خود، خط فرمان دیگری را اجرا کرده و جایگزین فرآیند خود می‌کند. در صورت استفاده، فهرست انتساب‌ها برای گنجاندن در پیام ارسالی باید با یک نویسه ";" (به عنوان آرگومان جداگانه) و به دنبال آن خط فرمان برای اجرا دنبال شود. این امکان «زنجیره‌سازی» دستورات را فراهم می‌کند، یعنی صادر کردن یک عملیات و بلافاصله پس از آن عملیاتی دیگر، بدون تغییر PIDها.

توجه داشته باشید که بسیاری از پوسته‌ها ";" را به عنوان جداکننده خط فرمان خود تفسیر می‌کنند، بنابراین زمانی که systemd-notify از یک پوسته فراخوانی می‌شود، نقطه ویرگول معمولاً باید به صورت "\;" گریز داده شود (escaped).

افزوده شده در نسخه 254.

--fd=

یک توصیف‌کننده فایل را همراه با پیام اعلان ارسال می‌کند. این گزینه هنگام فراخوانی در سرویس‌هایی که تنظیم FileDescriptorStoreMax= در آن‌ها فعال است مفید است؛ برای جزئیات systemd.service(5) را ببینید. توصیف‌کننده فایل مشخص‌شده هنگام فراخوانی باید به systemd-notify ارسال شود. این گزینه می‌تواند چندین بار برای ارسال چندین توصیف‌کننده فایل در یک پیام اعلان منفرد استفاده شود.

برای استفاده از این قابلیت از یک پوسته bash(1)، از عبارتی مانند زیر استفاده کنید:

systemd-notify --fd=4 --fd=5 4</some/file 5</some/other/file

افزوده شده در نسخه 254.

--fdname=

نامی را برای اختصاص دادن به توصیف‌کننده‌های فایلی که از طریق --fd= ارسال شده‌اند (بالا را ببینید) تنظیم می‌کند. این گزینه فیلد "FDNAME=" را کنترل می‌کند. این تنظیم فقط می‌تواند یک بار مشخص شود و برای همه توصیف‌کننده‌های فایل ارسال‌شده اعمال می‌شود. در صورتی که چندین توصیف‌کننده فایل با نام‌های متفاوت باید ارسال شوند، این ابزار را چندین بار فراخوانی کنید.

افزوده شده در نسخه 254.

--fork

به جای ارسال پیام اعلان، یک خط فرمان را منشعب (fork) کرده و منتظر می‌ماند تا پیام "READY=1" از آن دریافت شود. به عبارت دیگر: این گزینه systemd-notify را به جای فرستنده، به دریافت‌کننده پیام‌های اعلان تبدیل کرده و نقش‌ها را جابه‌جا می‌کند. این گزینه برای انشعاب سریع فرآیندی که پروتکل sd_notify() را از یک اسکریپت پوسته پیاده‌سازی می‌کند، مفید است. ورودی استاندارد و خروجی استاندارد خط فرمان فراخوانی‌شده به /dev/null متصل خواهند شد، اما خطای استاندارد از فرآیند فراخواننده به ارث برده می‌شود. شناسه عددی فرآیند توسط systemd-notify در خروجی استاندارد نوشته می‌شود (مگر اینکه --quiet مشخص شده باشد)، که بعداً می‌تواند برای خاتمه دادن به فرآیند منشعب‌شده استفاده شود.

توجه داشته باشید فرآیندهایی که بدین شکل منشعب می‌شوند احتمالاً پس از آنکه systemd-notify قبلاً بازگشته است همچنان در حال اجرا باقی خواهند ماند، که در نتیجه منجر به این می‌شود که والد جدید آن‌ها نزدیک‌ترین فرآیند دروگر (process reaper)، یعنی معمولاً مدیر سرویس به ازای هر کاربر یا مدیر سرویس سراسری سیستم شود.

توجه داشته باشید که این گزینه نباید برای فراخوانی موقت سرویس‌های کامل استفاده شود، برای این کار از systemd-run استفاده کنید.

همچنین توجه داشته باشید که در صورت فراخوانی با این سوییچ، systemd-notify تحت دو شرایط متمایز با موفقیت خارج خواهد شد:

1.systemd-notify یک اعلان "READY=1" از فرآیند فرزندی که به تازگی منشعب کرده است دریافت کرده باشد.
2.فرآیند فرزند قبل از ارسال "READY=1" به صورت تمیز (با کد خروج صفر) خارج شده باشد.

نمونه استفاده:

# PID=$(systemd-notify --fork -- mycommand)
...
kill "$PID"
unset PID

افزوده شده در نسخه 258.

--quiet, -q

هنگام استفاده از --fork، چاپ شناسه عددی فرآیند را خاموش می‌کند.

افزوده شده در نسخه 258.

-h, --help

یک متن راهنمای کوتاه را چاپ کرده و خارج می‌شود.

--version

یک رشته کوتاه نسخه را چاپ کرده و خارج می‌شود.

در صورت موفقیت، 0 برگردانده می‌شود؛ در غیر این صورت یک کد خطای غیر صفر برگردانده خواهد شد.

مثال 1. اعلان راه‌اندازی و به‌روزرسانی‌های وضعیت

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

#!/bin/sh
mkfifo /tmp/waldo
systemd-notify --ready --status="Waiting for data..."
while : ; do
        read -r a < /tmp/waldo
        systemd-notify --status="Processing $a"
        # Do something with $a ...
        systemd-notify --status="Waiting for data..."
done

systemd(1), systemctl(1), systemd.unit(5), systemd.service(5), sd_notify(3), sd_booted(3)

systemd 261.2