ایجاد محدودیت زمانی برای یک فرمان در لینوکس

وبلاگ ایجاد محدودیت زمانی برای یک فرمان در لینوکس

می‌خواهیم فرمانی به نام foo را در یک مدت زمانی خاص اجرا کنیم؛ به گونه‌ای که پس از این مدت زمان، این فرمان متوقف شود. چگونه میتوان برای یک فرمان در لینوکس  محدودیت زمانی ایجاد کرد؟ چگونه یک فرمان لینوکس اجرا کنیم و پس از N ثانیه، به صورت خودکار آن را متوقف کنیم؟

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

چگونه یک فرمان را در لینوکس با محدودیت زمانی اجرا کنیم؟

هدف ما در اینجا اجرای فرمانی با عنوان “ping www.ariasercive.net” با محدودیت زمانی ۳۰ ثانیه است؛

۱) باز کردن برنامه ترمینال

۲) اجرای فرمان ping و توقف آن پس از گذشت ۳۰ ثانیه:


timeout 30s ping www.ariasercive.net

۳) در همین حال، می‌توان فرمان sleep و دیگر فرمان‌های shell را نیز در آن ترکیب کرد:


ping www.ariasercive.net & sleep 30s; kill $!

حالا بیایید تمام فرمان‌ها و مثال‌ها را با جزئیات بررسی کنیم.

فرمان محدودیت زمانی در لینوکس

قالب کار برای فرمان timeout به صورت زیر است:


timeout DURATION COMMAND

timeout DURATION COMMAND arg1 arg2

timeout 1m ping google.com

timeout 30s tracepath www.arisercive.net

timeout [options] DURATION COMMAND arg1 arg2

متغیر DURATION یک عدد شناور با یک پسوند انتخابی به صورت زیر است:

  • s برای ثانیه (به صوت پیش‌فرض)
  • m برای دقیقه
  • h برای ساعت
  • d برای روز

ایجاد محدودیت زمانی ۸ ثانیه‌ای برای اجرای فرمان ping در لینوکس

برای این منظور، تایپ کنید:


date

timeout 8s ping www.cyberciti.biz

timeout 8s ping 192.168.2.254

date

ایجاد محدودیت زمانی برای فرمان ping در لینوکس

چگونه یک سیگنال را به گونه‌ای تنظیم کنیم که در پایان محدودیت زمانی ارسال شود؟

قالب کار به این صورت است:


timeout -s 9 YourCommandHere

timeout --signal=9 YourCommandHere

timeout -s 15 30s tracepath google.com

timeout -s 9 2m tail -F /var/log/secure

## send SIGTERM as terminate signal ##

timeout -s SIGTERM 5m ping google.com

برای دریافت لیست سیگنال‌ها، فرمان kill را به صورت زیر اجرا کنید:


kill -l

نمونه خروجی:


1) SIGHUP          2) SIGINT            3) SIGQUIT         4) SIGILL              5) SIGTRAP

6) SIGABRT        7) SIGBUS           8) SIGFPE            9) SIGKILL           10) SIGUSR1

11) SIGSEGV       12) SIGUSR2       13) SIGPIPE         14) SIGALRM      15) SIGTERM

16) SIGSTKFLT    17) SIGCHLD       18) SIGCONT      19) SIGSTOP       20) SIGTSTP

21) SIGTTIN        22) SIGTTOU      23) SIGURG        24) SIGXCPU      25) SIGXFSZ

26) SIGVTALRM                27) SIGPROF       28) SIGWINCH   29) SIGIO             30) SIGPWR

31) SIGSYS           34) SIGRTMIN    35) SIGRTMIN+1               36) SIGRTMIN+2               37) SIGRTMIN+3

38) SIGRTMIN+4               39) SIGRTMIN+5               40) SIGRTMIN+6               41) SIGRTMIN+7               42) SIGRTMIN+8

43) SIGRTMIN+9               44) SIGRTMIN+10            45) SIGRTMIN+11            46) SIGRTMIN+12            47) SIGRTMIN+13

48) SIGRTMIN+14            49) SIGRTMIN+15            50) SIGRTMAX-14            51) SIGRTMAX-13            52) SIGRTMAX-12

53) SIGRTMAX-11            54) SIGRTMAX-10            55) SIGRTMAX-9               56) SIGRTMAX-8               57) SIGRTMAX-7

58) SIGRTMAX-6               59) SIGRTMAX-5               60) SIGRTMAX-4               61) SIGRTMAX-3               62) SIGRTMAX-2

63) SIGRTMAX-1               64) SIGRTMAX

نحوه تنظیم مهلت زمانی

با استفاده از گزینه‌های –k یا –kill-after=DURATION می‌توانید برای فرمان در لینوکس محدودیت زمانی ایجاد کنید. به عنوان نمونه، مشخص کنید که اگر بعد از یک مدت زمانی خاص، فرمان هنوز هم در حال اجرا بود، سیگنال kill ارسال شود.


timeout -k=5 2m command1 arg1

timeout -k=5 -s SIGKILL 2m /path/to/my-app arg1 arg2

گزینه‌های دیگر:

گزینه –preserve-status این امکان را فراهم می‌کند که فرمان timeout با همان وضعیت نهایی فرمان به انتها برسد.


timeout --preserve-status 10s command1

گزینه –foreground وقتی مستقیماً از یک پرامپت shell اجرا نشده باشد، این امکان را فراهم می‌کند که فرمان از TTY خوانده شود و سیگنال‌های TTY را دریافت کند. در این حالت، زیرمجموعه‌ها یا اصطلاحاً فرزندان فرمان دارای محدودیت زمانی نخواهند بود.


timeout --foreground 1m command2

## Login to remote server. Run htop and die after 30seconds ##

timeout --foreground 30s ssh -t vivek@server1.cyberciti.biz htop

timeout --foreground 20s ssh -t vivek@centos7 top

راه حل دیگر برای ایجاد محدودیت زمانی برای یک فرمان در لینوکس

راه‌حل bash

قالب کار با کمک فرمان‌های read و kill نسبتاً ساده است:


MyCoolCommand Arg1 & read -t TIMEOUT_VALUE || kill $!

command arg1 & read -t 30 || kill $!

tail -F /var/log/secure & read -t 60 || kill $!

ping 192.168.2.254 & read -t 10 || kill $!

راه حل bash برای ایجاد یک محدودیت زمانی برای یک فرمان در لینوکس

متغیر $! شامل شناسه فرآیندی است که آخرین بار در پس‌زمینه اجرا شده است. در این مثال، این مورد به فرمان ping مربوط می‌شود.

یادداشتی بر فرمان تک‌خطی perl برای یونیکس، مک و بی‌اس‌دی

وقتی برنامه‌های بالا را نداشتید و یا علاقه‌ای به استفاده از آنها نداشتید، می‌توانید ترکیب فرمان‌های perl و shell را امتحان کنید. می‌توانید از فرمان تک‌خطی perl برای تنظیم یک هشدار استفاده کنید و سپس در یک محدودیت زمانی خاص، برنامه خود را اجرا نمایید. در هر صورت، باید نحوه کار برنامه‌تان را با SIGALRM تشخیص دهید. برنامه‌هایی که دارای بروزرسانی‌های دوره‌ای هستند، معمولاً از ALRM برای این منظور استفاده می‌کنند و به جای اینکه متوقف شوند، با دریافت این سیگنال آپدیت می‌شوند.


## define doalarm() shell  ##

doalarm() { perl -e 'alarm shift; exec @ARGV' -- "$@"; }

 

## timeout vim command after 600 seconds ##

doalarm 600 vim /path/to/demo.py

 

## timeout ping command after 10 seconds ##

doalarm 10 ping nixcraft.com

استفاده از فرمان تک‌خطی perl

جمع‌بندی

فرمان timeout یک روش ساده برای ایجاد محدودیت زمان برای یک فرمان در لینوکس است. در همین حال، استفاده از فرمان تک‌خطی perl در هنگام کار با یونیکس، مک و بی‌اس‌دی و زمانی که فرمان‌های timeout و bash در دسترس نیستند، می‌تواند مفید باشد. می‌توانید با تایپ فرمان man به صورت زیر، صفحه timeout man را نیز برای کسب اطلاعات بیشتر ببینید.