میخواهیم فرمانی به نام 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
چگونه یک سیگنال را به گونهای تنظیم کنیم که در پایان محدودیت زمانی ارسال شود؟
قالب کار به این صورت است:
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 $!
متغیر $! شامل شناسه فرآیندی است که آخرین بار در پسزمینه اجرا شده است. در این مثال، این مورد به فرمان 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
جمعبندی
فرمان timeout یک روش ساده برای ایجاد محدودیت زمان برای یک فرمان در لینوکس است. در همین حال، استفاده از فرمان تکخطی perl در هنگام کار با یونیکس، مک و بیاسدی و زمانی که فرمانهای timeout و bash در دسترس نیستند، میتواند مفید باشد. میتوانید با تایپ فرمان man به صورت زیر، صفحه timeout man را نیز برای کسب اطلاعات بیشتر ببینید.