4

I'm trying to execute a command for an x amount of seconds and then stop it afterwards. I guess normally you'd do this with the timeout command, but this program does not seem to be available on my machine, so I'm trying to still get this to work a different way.

Here's one of the commands I've tried:

./some_program & sleep 5; kill `pidof some_program`

Normally when I manually interrupt some_program using ctrl+c, it generates a csv file of the results, but the above command just seems to stop it, and there is no csv file that is created. If I use kill -9, it will terminate the program, but again, no csv file will be generated.

How can I automatically stop the program after an x number of seconds and still cause it to generate the csv file? (I've tried kill -2, kill -3 andkill -15.)

user2548144
  • 87
  • 1
  • 7
  • 1
    Why don't you run it in the background, catch the pid, sleep for X seconds and then kill it? – fedorqui Nov 29 '15 at 20:33
  • The & would put it in the background, right? Is it normal that when the above command finishes executing, the program is stopped and not killed (i.e. when i do `pgrep -lf some_program`, I still see that it's still there)? – user2548144 Nov 29 '15 at 20:42
  • When you say `command &` it keeps running in the background until it finishes... or you kill it. So if you still see it with `pgrep ...` (or with `ps -ef`, or...) it means that it is still running. The good thing of running it in the background is that it automaticallly "frees" your console to run a `sleep` command simiutlaneously and kill the script whenever you want. – fedorqui Nov 29 '15 at 20:44
  • 1
    so the problem is how to force your program to write the `.csv` file when it gets killed? You probably need to enhance the output program to recognize it has been interupted and write the file before it quits. You can probably do that in shell using `trap` and sending signals (via kill), but more traditionally done in a higher level language like `c` or `java` or `python` etc. Good luck. – shellter Nov 29 '15 at 20:51
  • @ferdoqui: Right, so when I do `./some_program & sleep 5; kill \`pidof some_program\``, it should run some_program in the background, sleep for 5 seconds, and then kill the program, right? The `kill \`pidof some_program\`` portion of the command seems to be stopping the program instead of killing it however, which is what I don't understand. If I use `kill -9 \`pidof some_program\`` it ends up killing the process, but no csv file is created, so I can't really use that. – user2548144 Nov 29 '15 at 20:56
  • Then this is probably something you should handle the way @shellter suggests: by using a higher level program like Python, C, etc that can handle such kills. – fedorqui Nov 29 '15 at 21:05
  • 1
    `kill -2` is equivalent to ctrl-c. So if you say the latter does result in the csv dump but the former doesn't then you should debug that first rather than the script you have described. Just start `some_program` manually and then in another terminal do a `kill -2`. Does that cause the program to dump the `csv`? If not then perhaps there is a bug in the signal handling of `some_program`. – kaylum Nov 29 '15 at 21:56
  • It's possible that you have `timelimit` installed - if so, you may be able to use that instead. – Toby Speight Jan 11 '16 at 19:01

1 Answers1

1

To get the same effect as C-c (assuming the program doesn't change tty settings to handle it in a non-standard way), you'll want to send SIGINT. Also, avoid running pidof - bash gives you the last background job as %+ when you use kill.

You should be able to

./some_program & sleep 5; kill -INT %+

Demonstration

$ time bash -c 'sleep 15 & sleep 3; kill -INT %+'

real    0m3.005s
user    0m0.001s
sys     0m0.004s
Toby Speight
  • 27,591
  • 48
  • 66
  • 103