Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deal with executing Unix command which produces an endless output

Tags:

process

scala

Some unix command such as tail -f or starting a python web server (i.e. cherrypy) will produce an endless output, i.e. the only way to stop it is to Ctrl-C. I'm working on a scala application which execute the command like that, my implemetation is:

import scala.sys.process._
def exe(command: String): Unit = {
    command !
}

However, as the command produces an endless output stream, the application hangs there until I either terminate it or kill the process started by the command. I also try to add & at the end of the command in order to run it in background but my application still hangs.

Hence, I'm looking for another way to execute a command without hanging my application.

like image 337
Long Thai Avatar asked Mar 14 '14 14:03

Long Thai


2 Answers

You can use a custom ProcessLogger to deal with output however you wish as soon as it is available.

val proc = 
  Process(command).run(ProcessLogger(line => (), err => println("Uh-oh: "+err)))

You may kill a process with the destroy method.

proc.destroy

If you are waiting to get a certain output before killing it, you can create a custom ProcessLogger that can call destroy on its own process once it has what it needs.

You may prefer to use lines (in 2.10; the name is changing to lineStream in 2.11) instead of run to gather standard output, since that will give you a stream that will block when no new output is available. Then you wrap the whole thing in a Future, read lines from the stream until you have what you need, and then kill the process--this simplifies blocking/waiting.

like image 82
Rex Kerr Avatar answered Nov 10 '22 00:11

Rex Kerr


Seq("sh", "-c", "tail -f /var/log/syslog > /dev/null &") !

works for me. I think Randall's answer fails because scala is just executing the commands, and can't interpret shell operators like "&". If the command passed to scala is "sh" and the arguments are a complete shell command, we work around this issue. There also seems to be an issue with how scala parses/separates individual arguments, and using a Seq instead of single String works better for that.

The above is equivalent to the unix command:

sh -c 'tail -f /var/log/syslog > /dev/null &'
like image 23
nairbv Avatar answered Nov 09 '22 23:11

nairbv