timeout
কমান্ডটি ব্যবহার করা সবচেয়ে ভাল হবে যদি আপনার কাছে এটির অর্থ বোঝানো থাকে:
timeout 86400 cmd
বর্তমান (8.23) জিএনইউ বাস্তবায়ন কমপক্ষে alarm()
শিশু প্রক্রিয়াটির জন্য অপেক্ষা করার সময় ব্যবহার করে বা সমতুল্য হয়ে কাজ করে । এটি প্রত্যাবর্তন এবং প্রস্থান করার SIGALRM
মধ্যে সরবরাহ করা থেকে রক্ষা করছে বলে মনে হচ্ছে না (কার্যকরভাবে সেই অ্যালার্মটি বাতিল করা )। এই ছোট উইন্ডো চলাকালীন, এমনকি স্টেডারে বার্তা লিখতে পারে (উদাহরণস্বরূপ, যদি শিশুটি একটি কোর ফেলে দেয়) যা আরও রেস উইন্ডোটি বাড়িয়ে তুলবে (অনির্দিষ্টকালের জন্য যদি স্ট্যাডার একটি সম্পূর্ণ পাইপ হয় তবে)।waitpid()
timeout
timeout
আমি ব্যক্তিগতভাবে সেই সীমাবদ্ধতার সাথে বেঁচে থাকতে পারি (যা সম্ভবত ভবিষ্যতের সংস্করণে স্থির করা হবে)। timeout
সঠিক প্রস্থান স্থিতি রিপোর্ট করতে, অন্য কোণার কেসগুলি হ্যান্ডেলগুলি (যেমন সিগালআরএম ব্লকড / স্টার্টআপে উপেক্ষা করা, অন্যান্য সিগন্যালগুলি হ্যান্ডেল করা ...) আপনি সম্ভবত হাতে হাতে পরিচালনা করার চেয়ে আরও ভাল যত্ন নেবেন।
একটি অনুমান হিসাবে, আপনি এটি লিখতে পারে perl
:
perl -MPOSIX -e '
$p = fork();
die "fork: $!\n" unless defined($p);
if ($p) {
$SIG{ALRM} = sub {
kill "TERM", $p;
exit 124;
};
alarm(86400);
wait;
exit (WIFSIGNALED($?) ? WTERMSIG($?)+128 : WEXITSTATUS($?))
} else {exec @ARGV}' cmd
Http://devel.ringlet.net/sysutils/timelimit/timelimit
এ একটি কমান্ড রয়েছে ( কয়েক মাসের মধ্যে জিএনইউর পূর্বাভাস দেয় )।timeout
timelimit -t 86400 cmd
এটির alarm()
মতো-মত প্রক্রিয়া ব্যবহার করে তবে SIGCHLD
বাচ্চা মারা যাচ্ছে তা সনাক্ত করতে একটি হ্যান্ডলার ইনস্টল করে (থামানো শিশুদের উপেক্ষা করে)। এটি চলার আগে অ্যালার্মটি বাতিল করে waitpid()
( SIGALRM
এটি মুলতুবি থাকা অবস্থায় সরবরাহ সরবরাহ বাতিল করে না , তবে এটি যেভাবে লেখা হয়েছে, আমি এটি কোনও সমস্যা হিসাবে দেখতে পাচ্ছি না) এবং কল করার আগে হত্যা করে waitpid()
(সুতরাং পুনরায় ব্যবহৃত পিডকে হত্যা করতে পারে না) )।
নেটপাইপের একটি timelimit
কমান্ডও রয়েছে। এটি এক দশক ধরে অন্য সমস্তগুলির পূর্বাভাস দেয়, আরও একটি পন্থা গ্রহণ করে তবে থামানো আদেশের জন্য সঠিকভাবে কাজ করে না এবং 1
সময়সীমা শেষ হওয়ার পরে একটি প্রস্থান স্থিতি ফিরে আসে ।
আপনার প্রশ্নের আরও সরাসরি উত্তর হিসাবে আপনি এরকম কিছু করতে পারেন:
if [ "$(ps -o ppid= -p "$p")" -eq "$$" ]; then
kill "$p"
fi
অর্থাৎ, পরীক্ষা করুন যে প্রক্রিয়াটি এখনও আমাদের একটি শিশু। আবার, একটি ছোট রেস উইন্ডো রয়েছে ( ps
সেই প্রক্রিয়াটির স্থিতি পুনরুদ্ধার এবং kill
এটি হত্যার মধ্যে) যার সময় প্রক্রিয়াটি মারা যেতে পারে এবং এর পিড অন্য প্রক্রিয়া দ্বারা পুনরায় ব্যবহার করা যেতে পারে।
কিছু শাঁস সঙ্গে ( zsh
, bash
, mksh
), আপনি pids পরিবর্তে কাজ চশমা পাস করতে পারেন।
cmd &
sleep 86400
kill %
wait "$!" # to retrieve the exit status
এটি কেবলমাত্র যদি কেবলমাত্র একটি ব্যাকগ্রাউন্ড জব থাকে (অন্যথায় সঠিক জবস্পেক পাওয়া সর্বদা নির্ভরযোগ্যভাবে সম্ভব হয় না) কাজ করে works
যদি এটি কোনও সমস্যা হয় তবে কেবল একটি নতুন শেল উদাহরণ শুরু করুন:
bash -c '"$@" & sleep 86400; kill %; wait "$!"' sh cmd
এটি কাজ করে কারণ শেলটি শিশু মারা যাওয়ার পরে কাজের টেবিল থেকে কাজটি সরিয়ে দেয়। এখানে, শেল কল হওয়ার পরে কোনও রেস উইন্ডো হওয়া উচিত নয় kill()
, হয় সিকচিলডি সিগন্যালটি পরিচালনা করা হয়নি এবং পিডটি পুনরায় ব্যবহার করা যাবে না (যেহেতু এটির জন্য অপেক্ষা করা হয়নি), বা এটি পরিচালনা করা হয়েছে এবং প্রক্রিয়া সারণী থেকে কাজ সরানো হয়েছে (এবং kill
একটি ত্রুটির কথা জানাবে)। bash
'গুলি kill
অন্তত ব্লক SIGCHLD এ আগেই প্রসারিত করতে তার কাজ টেবিল ব্যবহারের %
পর এবং এটি লোকটিকে অবরোধমুক্ত kill()
।
মৃত্যুর sleep
পরেও এই প্রক্রিয়াটি প্রায় ঝুলে থাকা এড়াতে আরেকটি বিকল্প হ'ল তার পরিবর্তে একটি পাইপ ব্যবহার করা বা হ'ল :cmd
bash
ksh93
read -t
sleep
{
{
cmd 4>&1 >&3 3>&- &
printf '%d\n.' "$!"
} | {
read p
read -t 86400 || kill "$p"
}
} 3>&1
এটির এখনও রেসের শর্ত রয়েছে এবং আপনি কমান্ডের প্রস্থান স্থিতি হারাবেন। এটি cmd
ধরেও নেয় এটি এর এফডি 4 বন্ধ করে দেয় না।
আপনি এই জাতীয়ভাবে একটি রেস-মুক্ত সমাধান বাস্তবায়নের চেষ্টা করতে perl
পারেন:
perl -MPOSIX -e '
$p = fork();
die "fork: $!\n" unless defined($p);
if ($p) {
$SIG{CHLD} = sub {
$ss = POSIX::SigSet->new(SIGALRM); $oss = POSIX::SigSet->new;
sigprocmask(SIG_BLOCK, $ss, $oss);
waitpid($p,WNOHANG);
exit (WIFSIGNALED($?) ? WTERMSIG($?)+128 : WEXITSTATUS($?))
unless $? == -1;
sigprocmask(SIG_UNBLOCK, $oss);
};
$SIG{ALRM} = sub {
kill "TERM", $p;
exit 124;
};
alarm(86400);
pause while 1;
} else {exec @ARGV}' cmd args...
(যদিও এটি অন্য ধরণের কোণার কেসগুলি পরিচালনা করার জন্য উন্নত করা দরকার)।
প্রক্রিয়া গ্রুপগুলি ব্যবহার করে অন্য একটি রেস-মুক্ত পদ্ধতি হতে পারে:
set -m
((sleep 86400; kill 0) & exec cmd)
তবে মনে রাখবেন যে প্রসেস গ্রুপগুলি ব্যবহার করে কোনও টার্মিনাল ডিভাইসে জড়িত I / O থাকলে পার্শ্ব-প্রতিক্রিয়া থাকতে পারে। এটির অতিরিক্ত সুবিধা রয়েছে যদিও এর ফলে তৈরি অন্যান্য সমস্ত অতিরিক্ত প্রক্রিয়াগুলি মেরে ফেলতে পারে cmd
।