system call that is killed after n seconds if not finished

J

Jaroslav Dobrek

Hello,

I would like to execute shell commands, but only if their execution
time is not longer than n seconds. Like so:

monitor(os.system("do_something"), 5)

I.e. the command do_somthing should be executed by the operating
system. If the call has not finished after 5 seconds, the process
should be killed.

How could this be done?

Jaroslav
 
A

Alain Ketterlin

Jaroslav Dobrek said:
I would like to execute shell commands, but only if their execution
time is not longer than n seconds. Like so:

monitor(os.system("do_something"), 5)

I.e. the command do_somthing should be executed by the operating
system. If the call has not finished after 5 seconds, the process
should be killed.

How could this be done?

My system (linux) has a timeout command that does just this. Otherwise,
you may use subprocess.Popen to spawn the process, sleep for 5 seconds
in the parent, then use Popen.poll() to check whether the process has
finished, and finally Popen.kill() if it has not.

-- Alain.
 
A

Adam Skutt

My system (linux) has a timeout command that does just this.

Alas, while timeout(1) is in GNU coreutils it's a rather recent
addition and so you cannot rely on it being on every Linux machine.
Also, there are multiple versions of timeout, from different
applications, that do the same thing with different syntax. However,
if it is available on the systems you care about, I would use it.
Pay close attention to its caveats.
Otherwise,
you may use subprocess.Popen to spawn the process, sleep for 5 seconds
in the parent, then use Popen.poll() to check whether the process has
finished, and finally Popen.kill() if it has not.

That's true subject to two conditions:
1. The subprocess doesn't spawn child processes of its own or you
don't care about killing them (doubtful).
2. The application isn't running on a command-line, where it could be
suspended; or you don't care about timeliness if the application is
suspended.

The first item can be solved by manually performing fork()/exec() and
using setpgid() to create a process group. Terminating the process
group on timeout will terminate the subprocess and all of its
children.

The second one is much more tricky to solve. Basically, you have to
supply enough job control functionality (like a shell) to handle the
terminal signals and ensure your signaling process stays alive. The
GNU coreutils version of timeout basically immunizes itself from the
signals, which works but also creates problems if it is run in the
background. If you need to do this, I'd advise cheating, as I believe
the general solution is pretty ugly and doesn't exist in ready form.
I certainly could not find it.

Adam
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top