Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hello All,
I want to execute a program using a shell script, but if the program does not terminates after a certain amount of time (lets say 5 m), I want to kill it in order to execute the same program again (my program sometimes terminates before 5 min). When the program terminates I want to save its results. So, my newbie shell script is the following...
num=1
for (( i = 1; i <= 100; i++ ))
do
./MyProgram
mv result.txt /home/bruno/output_I/result_00$0.txt
((num=num+1))
done
...or given for example an executable shell script named "/usr/local/myscript" and the 'at' service being available you could run 'echo "pkill -9 -f /usr/local/myscript"|/usr/bin/at "now + 5 minutes";'.
Tested the following script, but using the top command I can see that MyApp is not killed at all, since it accumulates as sleeping or running process at the CPU. Any tips?
#!/bin/bash
# the application you want to terminate after a while
prog=./MyApp
num=1
# the time you want to wait before killing it
time=1s
for (( i = 1; i <= 10000; i++ ))
do
${prog} &
sleep $time
kill %1
mv result.txt /home/bruno/output_I/result_00$num.txt
((num=num+1))
done
Hello All,
I want to execute a program using a shell script, but if the program does not terminates after a certain amount of time (lets say 5 m), I want to kill it in order to execute the same program again (my program sometimes terminates before 5 min). When the program terminates I want to save its results. So, my newbie shell script is the following...
num=1
for (( i = 1; i <= 100; i++ ))
do
./MyProgram
mv result.txt /home/bruno/output_I/result_00$0.txt
((num=num+1))
done
Regards!
You can try setting a ulimit
Code:
#!/bin/bash
ulimit -t 300
# the application you want to terminate after a while
prog=./MyApp
num=1
# the time you want to wait before killing it
time=1s
for (( i = 1; i <= 10000; i++ ))
do
${prog} &
sleep $time
kill %1
mv result.txt /home/bruno/output_I/result_00$num.txt
((num=num+1))
done
whcih limits the total amount of CPU time a process (or its children) can take, before system terminates it.
The problem is unless it is a mathematical, CPU bound process, most long term processes do not use CPU, they get locked into network or disk I/O waits. Even sleep does not use any real CPU.
This means that ulimit -t does not terminate a process after 300 seconds!
It is not a practical 'timeout' technique.
As for the 'looped' sleep.
I looked at this, and as a monitor it works reasonably well but has some problems...
1/ just counting sleep times does NOT add up to real time, as it does not take into account the time for the loop to process and check if the 'monitored process' has finished. The solution for that is to compare the current time against the time you started the monitor.
2/ It has a high time granulatity. A monitored process that worked well and finished quickly will still wait the 'sleep' period before the main process continues.
3/ You do not continue immeditally when the monitored task finishes, but still waits for that last sleep cycle to finish.
4/ A loop is complex. There is no need for it unless you want to report how long you have been waiting! A single sleep should suffice.
In summery...
For long tasks, that many minutes, this will be fine.
For network tasks (DNS lookups for example) where you want to abort earily because the network has failed (a typical reason to use a timeout), it can significant.
One second many not seem like much, but it can be a long time for computers, or even users who may be waiting.
My study looked at all these things, and solved them.
(see the links above)
Turn-key solution?
Yes in a way it is. BUT I also provide all the notes of the problems discovered, and how they were solved, in that solution. Better that someone else re-inventing the wheel, when they don't want to.
ASIDE: A 'signeled sleep' between the monitor and the main process may provide a even better solution, though that is not very simple to do in shell. I tried to write it so the final "timeout" program will work even with the old bourne shell.
A C (binary) version may better, but then how do you know it has handled these problems? I looked at a number, an many were incomplete solutions. Than C programs are not always as 'portible' as it is used to be.
for (( i = 1; i <= 10000; i++ ))
do
${prog} &
sleep $time
kill %1
mv result.txt /home/bruno/output_I/result_00$num.txt
((num=num+1))
done
Since you are immediately starting the next job and never explicitly performing a wait, the job number will not always be 1. I suggest that you use either "kill %%" or "kill %+", either of which will always refer to the most recently started background job (as will just "kill %", actually).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.