cgag
cgag

Reputation: 127

Running a process that waits on input in the background, without it pausing and without sending input

I have a program that does something like this in order to wait on someone pressing enter in order to quit:

spawnThreadAndDoStuff();
System.in.read();
System.exit(0);

I want to run it in the background indefinitely from a script, and just go kill it when I want it to end. I thought reading input from /dev/null would do this, but it doesn't seem to be working. My script looks like:

#!/bin/bash
java -cp someapp > mylog.log < /dev/null &

Am I doing this wrong, or is my approach just way off? What would the correct way to handle this be?

Upvotes: 3

Views: 3924

Answers (3)

Kaz
Kaz

Reputation: 58578

What you're doing wrong is that input from /dev/null behaves like a 0 byte file, and so the process hits EOF on standard input and quits. If /dev/null could hold a process that expects input, then this would work:

$ cat < /dev/null

But of course cat exits right away.

You're being bitten by the problem that you have a program with threads which reads from the TTY. As soon as you background it, because it is reading from the TTY, the tty driver sends it a SIGTTIN which stops all of its threads.

I would just rethink that program. If you want a program to work well in the background, do not have it read user input as a termination signal. Get rid of that read and kill it with signals when you want it to stop.

If you want both behaviors (background mode and user-quit mode) then make the program run-time configurable. One way would be simply to detect whether standard input is a TTY device or not. If it is a TTY device, then do the TTY read and quit. If it is not a TTY, then don't read: do an infinite sleep instead. Then your /dev/null standard input trick should work. /dev/null is not a TTY and so the process will just sleep.

(Do you have the isatty function in Java?)

Upvotes: 1

technosaurus
technosaurus

Reputation: 7802

command ... & thePIDofCOMMAND=$!

.... do stuff kill $thePIDofCOMMAND

Upvotes: 0

Emilio Silva
Emilio Silva

Reputation: 2141

Reading from /dev/null does not work because read immediately returns with an end-of-file.

This works for me:

(while true; do sleep 10000; done) | java -cp someapp > mylog.log &

The first command just sleeps forever, never providing any input.

Upvotes: 5

Related Questions