کاربرد دستور timeout در لینوکس – از صفر تا صد
دستور timeout در لینوکس برای تعیین سقف زمان پردازشهای مختلف روی رایانه استفاده میشود. بدین ترتیب، میتوان یک محدودیت زمانی، یعنی بیشینه زمانی که پردازش میتواند اجرا شود تعیین کرد. در این مقاله با استفاده از این دستور روی پردازشهای اجرایی محدودیت زمانی تعریف میکنیم. در ادامه با مجله فرادرس همراه باشید.
timeout به چه منظور استفاده میشود؟
دستور timeout همواره برای تعیین یک محدودیت به شکل طول زمان روی یک برنامه اجرایی استفاده میشود. اما شاید بپرسید دلیل انجام این کار چیست؟
یکی از موارد استفاده این دستور زمانی است که میخواهیم بدانیم یک پردازش دقیقاً چه مدت زمانی اجرا شده است. یک کاربرد رایج برای timeout، هنگام گزارشگیری (logging) یا بهرهگیری از برنامههای دریافت دادهها است به طوری که فایلهای لاگ فضای دیسک را به میزان نامحدودی اشغال نکنند.
کاربرد دیگر، زمانی است که نمیدانید یک پردازش چه هنگامی باید اجرا شود اما میدانید که نمیخواهید تا ابد اجرا شود. ممکن است این عادت را داشته باشید که پردازش ها را به اجرا درآورید و پس از اجرای آنها پنجره ترمینال را مینیمایز کرده و فراموش کنید که چه مواردی را اجرا کردهاید. اگر این عادت را دارید دستور Timeout برای شما بسیار کاربردی خواهد بود.
برخی برنامهها حتی برنامههای کاربردی ساده میتوانند در حدی روی شبکه ترافیک تولید کنند که در عملکرد آن اختلال ایجاد کنند. همچنین برخی از این برنامهها میتوانند منابع روی دستگاه را اشغال کنند و موجب کند شدن عملکرد سیستم شوند. این که اجازه دهیم این نوع برنامهها برای مدتهای طولانی در حالی که پشت سیستم نیستیم اجرا شوند یک رویه بد محسوب میشود.
timeout بخشی از GNU Core Utils است و از این رو لینوکس و سیستمهای Unix-like مانند macOS در داخل خود timeout را دارند. در این موارد نیازی به نصب چیز خاصی وجود ندارد و دستور timeout به صورت آماده به استفاده است.
آغاز کار با دستور timeout در لینوکس
در این بخش یک مثال ساده مطرح میکنیم. برای نمونه دستور ping با گزینههای پیشفرض خط فرمان خود تا زمانی که کلیدهای Ctrl+C را نزدهاید به کار خود ادامه میدهد. اگر آن را متوقف نکنید به کار خود تا همیشه ادامه خواهد داد.
ping 192.168.4.28
با استفاده از دستور timeout میتوانیم مطمئن باشیم که دستور ping تا ابد اجرا نخواهد شد و بدین ترتیب پهنای باند شبکه را اشغال نمیکند و دستگاههایی که پینگ میشوند را به زحمت نمیاندازد.
در دستور زیر از timeout استفاده کردهایم تا یک محدودیت زمانی برای دستور ping تعیین کنیم. بدین ترتیب ما اجازه میدهیم که دستور ping به مدت 15 ثانیه اجرا شود.
timeout 15 ping 192.168.4.28
پس از 15 ثانیه دستور timeout موجب خاتمه نشست ping میشود و به اعلان خط فرمان بازمیگردد.
استفاده از timeout به همراه واحدهای زمانی دیگر
اگر دقت کرده باشید ما در بخش قبلی از حرف s در انتهای زمان 15 ثانیه استفاده نکردیم. timeout فرض میکند که مقدار وارد شده به صورت پیشفرض ثانیه است. شما میتوانید یک s نیز به انتهای مقدار زمان اضافه کنید اما هیچ تفاوتی ایجاد نمیکند.
برای استفاده از زمان به صورت دقیق، ساعت یا روز میتوان به ترتیب حروف m ،h و یا d را به انتهای عدد مربوطه اضافه کرد.
برای این که دستور ping به مدت 3 دقیقه اجرا شود میتوانید از دستور زیر استفاده کنید:
timeout 3m ping 192.168.4.28
بنابراین دستور ping پیش از آن که timeout وارد شده و نشست ping را متوقف کند، به مدت 3 دقیقه اجرا خواهد شد.
محدودسازی دریافت دادهها با timeout
برخی فایلهایی که برای دریافت دادهها استفاده میشوند بسیار سریع رشد میکنند. برای جلوگیری از این که چنین فایلهایی اندازه بسیار زیاد و خارج از استاندارد پیدا کنند، میتوانید مقدار زمانی که برنامه دریافت داده اجرا میشود را محدود کنید.
در این مثال، ما از tcpdump استفاده میکنیم که یک ابزار دریافت ترافیک شبکه است. روی دستگاههای تست که در زمان نگارش این مقاله به بررسی این ابزار پرداختیم، tcpdump از قبل روی لینوکس اوبونتو و فدورا وجود دارد. اما روی لینوکسهای Manjaro و Arch Linux با دستور زیر نصب میشود:
sudo pacman -Syu tcpdump
ما میتوانیم دستور tcpdump را به مدت 10 ثانیه با گزینههای پیشفرض اجرا کنیم و با دستور زیر خروجی آن را به فایلی به نام capture.txt هدایت کنیم:
timeout 10 sudo tcpdump > capture.txt
نکته: tcpdump گزینههای خاص خود را برای ذخیرهسازی ترافیک شبکه در یک فایل دارد. ما از این روش سریع برای معرفی timeout استفاده میکنیم و نه برای معرفی tcpdump.
Tcpdump شروع به دریافت ترافیک شبکه میکند و ما به مدت 10 ثانیه صبر میکنیم. پس از گذشت 10 ثانیه tcpdump همچنان اجرا میشود و فایل capture.txt اندازهاش افزایش مییابد.
اگر اندازه فایل capture.txt را با دستور ls بررسی کنیم میبینیم که اندازه آن در طی چند ثانیه 209 کیلوبایت شده است. بنابراین میتوان تصور کرد که در طی زمان چه قدر افزایش پیدا میکند.
ls -lh capture.txt
چنان که میبینید دستور timeout موجب توقف tcpdump شده است. این کار از طریق ارسال سیگنال صورت میگیرد.
ارسال سیگنال صحیح
زمانی که timeout میخواهد یک برنامه را متوقف کند یک سیگنال SIGTERM به آن ارسال میکند. این سیگنال محترمانه تقاضا میکند که برنامه خاتمه یابد. برخی برنامهها ممکن است سیگنال SIGTERM را نادیده بگیرند. زمانی که چنین حالتی رخ بدهد، باید به timeout بگوییم که از نیروی بیشتری استفاده کند.
این کار از طریق ارسال سیگنال SIGKILL میسر است. سیگنال SIGKILL نمیتواند نادیده گرفته شود و یا مسدود گردد. این سیگنال همواره کار خود را انجام میدهد. SIGKILL مؤدبانه از برنامه تقاضای توقف نمیکند. SIGKILL در یک گوشه با کرنومتر و چوبی در دست منتظر میایستد.
ما میتوانیم از گزینه (سیگنال) s- برای اعلام ارسال سیگنال SIGKILL به دستور timeout استفاده کنیم.
timeout -s SIGKILL 10 sudo tcpdump > capture.txt
این بار به محض این که 10 ثانیه بگذرد، tcpdump متوقف میشود.
تقاضای اولیه به صورت مؤدبانه
ما میتوانیم از timeout بخواهیم که با ارسال سیگنال SIGTERM از برنامه به صورت مؤدبانه بخواهد که خاتمه یابد و در صورتی که گوش نداد تنها آن زمان سیگنال SIGTERM را ارسال کند.
به این منظور باید از گزینه k- استفاده کنید. گزینه k- باید یک پارامتر زمان نیز داشته باشد.
در دستور زیر ما از timeout میخواهیم که به dmseg 30 ثانیه فرصت بدهد و سپس آن را با سیگنال SIGTERM خاتمه ببخشد. اگر dmseg پس از 40 ثانیه همچنان در حال اجرا بود، این بدان معنی است که تقاضای دیپلماتیک SIGTERM نادیده گرفته شده است و timeout باید سیگنال SIGKILL را برای پایان کار ارسال کند.
dmseg ابزاری است که میتواند پیامهای بافر حلقه کرنل را مورد نظارت قرار دهد و آنها را در پنجره ترمینال نمایش دهد.
timeout -k 40 30 dmseg –w
dmseg به مدت 30 ثانیه اجرا میشود و زمانی که سیگنال SIGTERM را دریافت کند متوقف میشود.
میدانیم که این سیگنال SIGKILL نیست که dmseg را متوقف کرده است زیرا dmseg همواره یک مقدار بازگشتی به صورت killed دارد که نشاندهنده خاتمه یافتن پردازش است و در این مورد آن پیام نمایش نیافته است.
بازیابی کد خروج
برنامههای با رفتار مناسب، زمانی که خاتمه مییابند یک مقدار را به پوسته ارسال میکنند. این پیام به نام کد خروج نامیده میشود. به صورت معمول این پیام برای اعلام این نکته به پوسته یا هر پردازش دیگری که برنامه را اجرا کرده بود استفاده میشود که مشخص کند برنامه در زمان اجرا با چه مشکلاتی مواجه شده است.
Timeout کد خروج خاص خود را دارد، اما این کد برای ما اهمیتی ندارد. ما احتمالاً به کد خروج پردازشی که timeout کنترل میکند بیشتر علاقهمند هستیم.
دستور زیر اجاره میدهد که ping به مدت چند ثانیه اجرا شود. در این مدت رایانهای به نام Nostromo که روی یک شبکه تست قرار دارد پینگ میشود. ما از این رایانه برای اجرای تستهای این مقاله استفاده کردهایم.
timeout 5 ping Nostromo.local
این دستور به مدت پنج ثانیه اجرا میشود و timeout آن را خاتمه میبخشد. در ادامه میتوانیم با استفاده از دستور زیر بررسی کنیم که کد خروج چیست:
echo $?
کد خروجی 124 است. این مقداری است که timeout برای نشان دادن این که برنامه با استفاده از SIGTERM خاتمه یافته است استفاده میکند. اگر سیگنال SIGTERM موجب خاتمه برنامه شود کد خروج 137 خواهد بود.
اگر برنامه با Ctrl+C متوقف شود، کد خروج دستور timeout برابر با 0 خواهد بود.
timeout 5 ping Nostromo.local
echo $?
اگر اجرای برنامه پیش از خاتمه یافتن timeout پایان یابد، دستور timeout میتواند کد خروجی از برنامه را به پوسته بازگشت دهد.
خروج داوطلبانه
برای این که این حالت اتفاق بیفتد برنامه باید خودش را خاتمه ببخشد، یعنی timeout موجب خاتمه آن نشود و باید از گزینه preserve-status-- نیز استفاده شود.
اگر در دستور پینگ از گزینه c- به همراه مقدار 5 استفاده کنیم تنها پنج درخواست ارسال میشود. اگر مدت زمان timeout را روی یک دقیقه تنظیم کنیم، دستور ping در نهایت از سوی خودش متوقف میشود. در این حالت میتوانیم کد خروجی را با دستور echo بررسی کنیم.
timeout --preserve-status 1m ping -c 5 Nostromo.local
echo $?
در این حالت، دستور ping پنج درخواست خود را تکمیل میکند و خاتمه مییابد. کد خروج نیز صفر است.
برای تأیید این که کد خروج از سوی ping میآید، میتوانیم ping را مجبور کنیم که یک کد خروج متفاوت تولید کند. اگر تلاش کنیم درخواستهای ping را به یک آدرس IP ناموجود ارسال کنیم، ping با کد خروج error ناموفق خواهد بود. در این صورت میتوانیم از دستور echo برای بررسی کد خروج غیر صفر استفاده کنیم.
timeout --preserve-status 1m ping -c 5 NotHere.local
echo $?
بدیهی است که دستور ping نمیتواند به دستگاه ناموجود برسد و از این رو گزارش خطا تولید کرده و خارج میشود. کد خروج در این حالت 2 است. این کد خروجی است که ping برای خطاهای عمومی استفاده میکند.
سخن پایانی
دستور timeout برای ایجاد نوعی محدودیت روی زمانهای اجرا برنامهها استفاده میشود. اگر این احتمال وجود دارد که فایلهای لاگ باعث اشغال کل فضای دیسک شوند و یا ابزار شبکهای فراموش شود و در حالت اجرا بماند میتوان آن را به کمک دستور timeout استفاده کرد و اجازه داد که رایانه خودش موضوع را مدیریت کند.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای لینوکس (Linux)
- گنجینه آموزشهای لینوکس (Linux)
- مجموعه آموزشهای دروس علوم و مهندسی کامپیوتر
- سیستم عامل لینوکس — راهنمای جامع
- لینوکس اوبونتو و هر آنچه برای شروع به کار با آن باید بدانید — راهنمای جامع به زبان ساده
==