views:

77

answers:

4

On a linux box I've got a python script that's always started from predefined user. It may take a while for it to finish so I want to allow other users to stop it from the web.

Using kill fails with Operation not permitted.

Can I somehow modify my long running python script so that it'll recive a signal from another user? Obviously, that another user is the one that starts a web server.

May be there's entirely different way to approach this problem I can't think of right now.

A: 

You could use sudo to perform the kill command as root, but that is horrible practice.

How about having the long-running script check some condition every x seconds, for example the existence of a file like /tmp/stop-xyz.txt? If that file is found, the script terminates itself immediately.

(Or any other means of inter-process communication - it doesn't matter.)

Pekka
+1  A: 

If you do not want to execute the kill command with the correct permissions, you can send any other signal to the other script. It is then the other scripts' responsibility to terminate. You cannot force it, unless you have the permissions to do so.

This can happen with a network connection, or a 'kill' file whose existence is checked by the other script, or anything else the script is able to listen to.

relet
+1  A: 

Off the top of my head, one solution would be threading the script and waiting for a kill signal via some form or another. Or rather than threading, you could have a file that the script checks every N times through a loop - then you just write a kill signal to that file (which of course has write permissions by the web user).

I'm not terribly familiar with kill, other than killing my own scripts, so there may be a better solution.

Wayne Werner
+1  A: 

If you set up your python script to run as a deamon (bottom of page under Unix Daemon) on your server (which sounds appropriate), and you give the apache user permissions to execute the init.d script for the service, then you can control the service with php code similar to this (from here - the service script name in this case is 'otto2'):

<? 
$otto = "/usr/etc/init.d/otto2 "; 

if( $_GET["action"] ) { 
    $ret = shell_exec( $otto.$_GET["action"] ); 
    //Check your ret value  
} 
else { 
    ?> 
    <a href="<?=$PHP_SELF?>?action=start">Start  </a> 
    <a href="<?=$PHP_SELF?>?action=stop">Stop  </a> 
    <? 
} 

?>

The note on that is 'really basic untested code' :)

sje397