Omid Ataollahi
Omid Ataollahi
خواندن ۴ دقیقه·۳ سال پیش

اجرای خودکار اسکریپت بعد از unlock کردن در لینوکس

یکم عنوانش بدجور شد ولی خلاصه ماجرا اینه که:
من نیاز داشتم که هر بار که پسورد لپتاپم رو وارد می‌کنم و وارد سیستم‌عامل میشم یه دستورِ به خصوص اجرا بشه.

به طور دقیق‌تر بخوام بگم قضیه اینه که:
من به طور معمول لپتاپم رو خاموش نمی‌کنم و همیشه sleep می‌کنم. همچنین سرویس مورد علاقه‌ام برای رد شدن از فیل*تر*ینگ tor هست که آزاد و اوپن سورسه.
ازونجایی که دوستان در حال تغییر زیرساخت‌ها هستند دائماً و شاهد قطع و وصلی هستیم (هم در کل اینترنت و هم در سرویس tor) و با هر بار قطع اتصال، tor نیاز داره که یه بار ریستارت بشه تا دوباره بتونه متصل بشه، تصمیم گرفتم که دستور ریستارت شدن tor رو به طور اتوماتیک اجرا کنم و یکی از بهترین موقعیت‌ها برای ریستارت کردن tor، زمانی هست که من تازه لپتاپ رو باز می‌کنم و شروع می‌کنم به کار کردن.

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

مرحله اول

یک جوری باید بفهمیم که کِی لپتاپ lock شده و کِی unlock شده!

توی لینوکس یه محلی وجود داره به اسم D-Bus که کارش اینه که:
هر پروسسِ لینوکسی که بخواد پیامی رو به همه‌ی پروسس‌های دیگه اعلام کنه، می‌تونه پیامش رو به D-Bus بفرسته تا اونجا نوشته بشه. حالا بقیه پروسس‌ها هر موقع که دلشون خواست میان و اون پیام رو می‌ببین. (مثل یک تابلوی اعلانات)

اون پروسسی در لینوکس که مسئول lock و unlock کردن سیستم‌عامل هست، اسمش هست systemd-logind که دقیقاً هر بار بعد از انجام مسئولیتش یک پیام توی D-Bus ثبت می‌کنه که عمل lock یا unlock انجام شد. این پیام رو هم توی قسمت org.freedesktop.login1 ثبت می‌کنه که یه بخشی (آبجکتی) از D-Bus محسوب میشه.

ما چطور می‌تونیم از روی D-Bus این پیام رو بخونیم تا متوجه بشیم که الان وقت اجرای دستور دلخواه‌مون(مثلا ریستارت کردن tor) هست یا نه؟

با دستور (برنامه‌ی) gdbus میشه با D-Bus ارتباط برقرار کرد. ترمینال رو باز کنید و دستور زیر رو بزنید:

gdbus monitor -y -d org.freedesktop.login1

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

حالا کافیه که خروجی رو طوری فیلتر کنید که فقط کلمه true و false برگرده:

gdbus monitor -y -d org.freedesktop.login1 | grep --line-buffered -i &quotLockedHint&quot | sed -uE 's/.*LockedHint.*<(.*)>.*/\1/g'

اینا چند تا ابزار ساده‌ی لینوکسی هستن که پیش‌نیاز این آموزش محسوب میشن! (خودتون سرچ کنید اگر بلدشون نیستید)

حالا کافیه که توی یه حلقه‌ی بینهایت، همیشه منتظر دیدن کلمه false (در اینجا به معنی unlock شدن سیستم) بمونید:

gdbus monitor -y -d org.freedesktop.login1 | grep --line-buffered -i &quotLockedHint&quot | sed -uE 's/.*LockedHint.*<(.*)>.*/\1/g' | while read x; do case &quot$x&quot in &quotfalse&quot) sudo systemctl restart tor;; esac done

این تکه کد رو در یک فایل با عنوان دلخواه و در محل دلخواه ذخیره کنید (مثلاً در این آموزش من اسمش رو گذاشتم restart-tor-after-unlock.sh و همچنین در پوشه home ذخیره‌ش کردم).

مرحله دوم

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

sudo chmod +x restart-tor-after-unlock.sh

بعد لازمه که به user مون اجازه‌ی اجرای دستور systemctl رو بدیم. با دستور sudo visudo وارد فایل sudoers بشید و خط زیر رو به آخرش اضافه کنید:

your-user-name ALL=(ALL) NOPASSWD:/usr/bin/systemctl

دقت کنید که به جای your-user-name نام یوزر واقعی خودتون رو بزنید.

مرحله سوم

حالا باید یک سرویس (systemd service) بسازیم تا اسکریپت آماده شده در مرحله اول رو بتونیم همیشه در حالت اجرا نگه داریم. پس بزنید:

sudo vim /etc/systemd/system/restart-tor-after-unlock.service

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

[Unit] Description=restart tor after unlock StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=omid ExecStart=/bin/bash -c &quot~/restart-tor-after-unlock.sh&quot Environment=&quotPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin&quot [Install] WantedBy=multi-user.target

تذکر: در قسمت User اسم یوزر خودتون رو بنویسید طبیعتاً.

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

sudo systemctl enable restart-tor-after-unlock

حالا هم لپتاپ رو ریستارت می کنیم یا بهتر اینکه دستور زیر رو می‌زنیم تا سرویس شروع به کار کنه:

sudo systemctl start restart-tor-after-unlock

حالا همه‌چی آماده‌س. امتحان کنید و احتمالا با کمی سرچ و تغییرات به اون چیزی که دلخواه‌تونه خواهید رسید.


واسه این زیبایی‌های لینوکسه، که عاشقشم.

پ.ن۱: اگر احیاناً به دلیل بی‌سلیقه‌گی ویرگول، در خوندن کد‌ها دچار مشکل هستید، کد رو تا چند روز آینده توی گیت‌هاب هم خواهم گذاشت.

پ.ن۲: عملِ unlock کردن و login کردن، تفاوت مهمی داره. من در این مقاله در مورد unlock توضیح دادم. ولی اگه نیازِ شخصیِ شما با login برطرف میشه، با یه سرچ کوتاه پیداش خواهید کرد.

لینوکسبرنامه نویسیtorتور
شاید از این پست‌ها خوشتان بیاید