When I write the following code (in ammonite but i don't think it matters)
("tail -f toTail.txt" lineStream) foreach(println(_))
, the program give me the last line as intend but then hang, and even if i write more in the file, nothing come out.
How does the API support process that have unbounded output ?
I try to write val myStream = ("tail -f toTail.txt" lineStream_!)
but it still does not return write away
Here is what the scala doc says:
lineStream: returns immediately like run, and the output being generated is provided through a Stream[String]. Getting the next element of that Stream may block until it becomes available.
Hence i don't understand why it blocks
By the way i am having exactly the same behavior with the Ammonite API
If type %%("tail", "-f", "toTail.txt")
once again the method just hang and does not return immediately.
There is no issue with the ProcessBuilder (at least not one that stems from your use case). From the ProcessBuilder documentation:
The documentation clearly states that
lineStream
might block until the next line becomes available. Since the nature oftail -f
is an infinite stream of lineslineBreak
the program will block waiting for the next line to appear.For the following assume I have a file:
/Users/user/tmp/sample.txt
and it's contents are:Why
lineStream_!
isn't wrongOutputs:
So you see that the
lineStream_!
returned immediately. Because the nature of the command is finite.How to return immediately from a command that produces infinite output:
Let's try this with
tail -f
. You need more control over your process. Again, as the documentation states:So for an example:
Outputs:
It still returns immediately and now it just hangs there waiting for more input. If I do
echo 'fff' >> sample.txt
from thetmp
directory, the program outputs:You now have the power to perform any computation you want after issuing a
tail -f
command and the power to terminate it depending on the condition you pass to thetakeWhile
method (or other methods that close the input stream).For more details on
ProcessIO
check the documentation here.I think, this has to do with how you are adding data to the file, not with the
ProcessBuilder
. If you are using it in an editor for example to add data, it rewrites the entire file every time you save, with a different inode, andtail
isn't detecting that.Try doing
tail -F
instead oftail -f
, that should work.