1

I have a loop where I run an installed program using os.system("program + arguments") passing each element in the loop as an argument to the program. Runtime of the program changes according to the argument, sometimes it takes a second and sometimes it takes hours. So I want to kill the program when it took more than an hour and proceed to the next element in the loop.

I tried to use the second answer here (because I couldn't understand how I could use the best answer) Python: Run a process and kill it if it doesn't end within one hour by replacing os.sytem("program+arguments") to subprocess.Popen(["program+arguments"]) but it gives "No such file or directory error", I'm sure I'm passing the arguments correctly, could you help me how I can apply such solution?

Here is the error message,

subp = subprocess.Popen(["home/admin/Desktop/molblocks/fragment -i " + OrgDir+"/"+compsmi + " -r "+ RulesPath + " -e -n "+str(FragLength) + " -o " + compsmi + "_frag.txt"])

 File "/usr/lib64/python2.7/subprocess.py", line 709, in __init__
    errread, errwrite)

File "/usr/lib64/python2.7/subprocess.py", line 1326, in _execute_child
    raise child_exception

Best Regards!

Community
  • 1
  • 1
patti_jane
  • 3,293
  • 5
  • 21
  • 26
  • You could try spawning it in a different thread, then kill the thread. – Carcigenicate Oct 28 '16 at 21:21
  • show the command line you're trying to execute. `program+arguments` is essentially useless. You ARE calling popen properly, but whatever you're passing in is WRONG, hence "no such file or directory". – Marc B Oct 28 '16 at 21:25
  • if it's under windows, you probably forgot to quote a path, so that `.popen("c:\program files\blah blah blah"` is trying to execute a program named `c:\program` with arguments `files\blah blah blah` – Marc B Oct 28 '16 at 21:26
  • @MarcB I twice checked the paths and they're alright, it's under linux – patti_jane Oct 28 '16 at 21:29
  • "alright" doesn't help us figure out the problem. Show the command. – Marc B Oct 28 '16 at 21:30
  • there you go: `home/admin`... there's no leading `/`, so unless your script's running with `/` as its current working directory. that path is wrong. And don't post blobs of text into a comment. edit your question and put it there. – Marc B Oct 28 '16 at 21:32
  • @MarcB Ok, but before using subprocess the same command worked just fine with os.system, I don't get the difference - Adding "/" did not work actually, it gave the same error. – patti_jane Oct 28 '16 at 21:44
  • did you check what directory the subprocess starts up in? – Marc B Oct 28 '16 at 21:45
  • @MarcB I'm running the python script in a different directory than where the program is, shouldn't it start up where it's located, in ../Desktop/molblocks/.. ? – patti_jane Oct 28 '16 at 21:49

2 Answers2

1

On Unix, if args is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program. (When shell is not True)

https://docs.python.org/2/library/subprocess.html#subprocess.Popen.

Try this:

subp = subprocess.Popen(["home/admin/Desktop/molblocks/fragment", "-i", (OrgDir+"/"+compsmi), "-r", RulesPath, "-e", "-n", str(FragLength), "-o", (compsmi+"_frag.txt")])
Niranjan
  • 86
  • 1
  • 4
0

You can setup a timer to kill the process like so

import subprocess
import threading

proc = subprocess.call("program + arguments", shell=True)
timer = threading.Timer(3600, proc.kill)
timer.cancel()
proc.wait()

The call, check_call and Popen calls accept programs in two forms. Either a single string ("program arg1 arg2") that should be passed to a subshell (you need shell=True to make it work) or a list of parameters ["program", "arg1", "arg2"] (shell=True is optional an on linux a bit more efficient if you don't use a subshell). You put put the program + args as a single item in a list and python dutifully escaped all of the separators and tried to run a program of that whole name.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • Thanks, i'll try it. Python documentation says, using shell=True can be a security hazard, is it safe to use this method since I share a server with other people? – patti_jane Oct 28 '16 at 21:54
  • As for security, its kinda like a [sql injection attack](https://xkcd.com/327/) for the shell. Suppose you take input from an untrusted user and instead of a user name somebody types `";rm -rf /"` - the shell saw the semicolon, started a new command, and you just blew your server away! The fix is easy, you could call `shlex.quote` for that field. Python does the same thing when you use the list form. In `["prog", ";rm -rf /"]` that second arg is quoted and is safe. shell=true is fine as long as you quote any bits of data from users. – tdelaney Oct 29 '16 at 00:03