5

If the input is interactive, i.e. from the console, I want to print a command prompt e.g. ">"

But if it is redirected e.g. from a file, then I do not want to prompt.

System.in is an abstract InputStream which does not appear to have any method for this.

Maybe you could use instanceof if the concrete type is different?

As well, if System.out is redirected to a file I also do not want to prompt

Andrew McKinlay
  • 2,431
  • 1
  • 24
  • 27
  • For a linux-specific solution using JNI, see [here](http://stackoverflow.com/a/18371202/446591). You'd just need to change `fileno(stderr)` to `fileno(stdin)`. – Brad Mace Aug 22 '13 at 03:29
  • 1
    possible duplicate of [How can I check if a Java program's input/output streams are connected to a terminal?](http://stackoverflow.com/questions/1403772/how-can-i-check-if-a-java-programs-input-output-streams-are-connected-to-a-term) – Kristian Holdhus May 02 '14 at 01:49

2 Answers2

5

AFAIK, there is no way to do this in pure Java, and even doing it in JNI / JNA would be complicated.

An alternative might be to use the new Console API introduced in JDK 1.6. This allows you to try to get a reader/writer for the console. If it succeeds, the result is guaranteed to be interactive ... in the sense that you mean.

A second alternative would be to do the "check for interactivity" in the wrapper script that you use to launch your application, and pass the information to Java via the system properties. For instance, on a GNU/Linux system the tty(1) command can be used to tell if stdin is a connected to a "tty" device.


Note that there are other ways to deal with a requirement to avoid unwanted prompts when running non-interactively:

If System.out is redirected to a file I also do not want to prompt.

(I think you might mean that System.in is redirected. That is the normal way to non-interactively run an application that normally takes interactive input from the user ...)

The alternatives include:

  • You could modify the program to write the prompts to (say) System.err and redirect that to a different place.

  • You could modify the program to have options that mean "don't prompt" or "take input from a file".

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    That should work. It sounds like System.console() will return null if there is no console attached. http://java.sun.com/javase/6/docs/api/java/io/Console.html – Andrew McKinlay Mar 10 '10 at 00:22
  • 1
    The Console API works in one sense, but if the user wants the app's input from a (say) a file, then opening a new console stream subverts. IMO, the Console API should only be used when it makes no sense (or is dangerous) for the application to read from a non-interactive stdin. – Stephen C Mar 10 '10 at 00:44
  • I wasn't thinking of opening a new console stream. I was just thinking you could check for a non-null return from System.console() to determine if you were attached to a console. – Andrew McKinlay Mar 11 '10 at 14:18
  • 1
    @Andrew - but how does that help? It does NOT tell you is System.in/out are attached to a console. – Stephen C Mar 11 '10 at 21:44
  • Yeah, you're right, I wasn't thinking. It only tells you if if java was started from a console, but obviously stdin/out could still be redirected. – Andrew McKinlay Mar 13 '10 at 13:26
0

Since Java 6 there is the method java.lang.System.console():

Whether a virtual machine has a console is dependent upon the underlying platform and also upon the manner in which the virtual machine is invoked. If the virtual machine is started from an interactive command line without redirecting the standard input and output streams then its console will exist and will typically be connected to the keyboard and display from which the virtual machine was launched. If the virtual machine is started automatically, for example by a background job scheduler, then it will typically not have a console.

If this virtual machine has a console then it is represented by a unique instance of this class which can be obtained by invoking the java.lang.System.console() method. If no console device is available then an invocation of that method will return null.

tangens
  • 39,095
  • 19
  • 120
  • 139