Suppose we have the following Scala (2.12). It is using ProcessBuilder to execute a very trivial set of commands (a sleep
, followed by an echo
). The program also captures both stdout and stderr, and prints all lines - with those respective prefixes - to either stdout or stderr of the Scala process itself.
import scala.sys.process._
import scala.language.postfixOps
object BackgroundProcessRedirect {
def main(args: Array[String]) = {
val output = "sleep 5" #&& s"echo myoutput" lineStream_! ProcessLogger(line => System.err.println(s"stderr: $line"))
output.foreach(line => System.out.println(s"stdout: $line"))
}
}
When executed on OS X, either in zsh
5.6.2 or GNU bash
4.4.23(1), the process becomes suspended due to tty output unless stdin is attached. This happens despite the fact that neither command (sleep
nor echo
) should be trying to read from stdin.
# first, compile
scalac BackgroundProcessRedirect.scala
# now, run as a background process, redirecting stdout and stderr to files
scala BackgroundProcessRedirect >/tmp/scala.out 2>/tmp/scala.err &
# after 5 seconds, the process is suspended, as in the following jobs output
[1] + <PID> suspended (tty output) scala BackgroundProcessRedirect > /tmp/scala.out 2> /tmp/scala.err
# now, foreground the process; it will complete immediately
fg
# the output file contents are as expected
cat /tmp/scala.out
stdout: myoutput
# run the same thing again, but this time redirect stdin from /dev/null
scala BackgroundProcessRedirect </dev/null >/tmp/scala.out 2>/tmp/scala.err &
# now, the process completes normally after 5 seconds (not suspended), and the file contents are as expected
cat /tmp/scala.out
stdout: myoutput
If the program is simply run in the foreground to begin with, then it also doesn't become suspended. Any ideas what could be causing this?
Running stty -tostop
in either the terminal that launches scala
, or in a new script file that invokes these same commands, and is then invoked by scala
, has no effect on this behavior.