How can I check if a Java program's input/output streams are connected to a terminal? How can I check if a Java program's input/output streams are connected to a terminal? java java

How can I check if a Java program's input/output streams are connected to a terminal?


System.console() vs isatty()

System.console(), as already mentioned by @Bombe, works for simple use cases of checking console-connectedness. The problem with System.console() however, is that it doesn't let you determine whether it's STDIN or STDOUT (or both or neither) that is connected to a console.

The difference between Java's System.console() and C's isatty() can be illustrated in the following case-breakdown (where we pipe data to/from a hypothetical Foo.class):

1) STDIN and STDOUT are tty

%> java FooSystem.console() => <Console instance>isatty(STDIN_FILENO) => 1isatty(STDOUT_FILENO) => 1

2) STDOUT is tty

%> echo foo | java FooSystem.console() => nullisatty(STDIN_FILENO) => 0isatty(STDOUT_FILENO) => 1

3) STDIN is tty

%> java Foo | catSystem.console() => nullisatty(STDIN_FILENO) => 1isatty(STDOUT_FILENO) => 0

4) Neither STDIN nor STDOUT are tty

%> echo foo | java Foo | catSystem.console() => nullisatty(STDIN_FILENO) => 0isatty(STDOUT_FILENO) => 0

I can't tell you why Java doesn't support better tty-checking. I wonder if some of Java's target OS's don't support it.

Using JNI to call isatty()

It technically is possible to do this in Java (as stephen-c@ pointed out) with some fairly simple JNI, but it will make your application dependent on C-code that may not be portable to other systems. I can understand that some people may not want to go there.

A quick example of what the JNI would look like (glossing over a lot of details):

Java: tty/TtyUtils.java

public class TtyUtils {    static {        System.loadLibrary("ttyutils");    }    // FileDescriptor 0 for STDIN, 1 for STDOUT    public native static boolean isTty(int fileDescriptor);}

C: ttyutils.c (assumes matching ttyutils.h), compiled to libttyutils.so

#include <jni.h>#include <unistd.h>JNIEXPORT jboolean JNICALL Java_tty_TtyUtils_isTty          (JNIEnv *env, jclass cls, jint fileDescriptor) {    return isatty(fileDescriptor)? JNI_TRUE: JNI_FALSE;}

Other languages:

If you have the option of using another language, most other languages I can think of support tty-checking. But, since you asked the question, you probably already know that. The first that come to mind for me (aside from C/C++) are Ruby, Python, Golang and Perl.


System.console() will return the console your application is connected to if it is connected, otherwise it returns null. (Note that it’s only available from JDK 6 on.)


The short answer is that there is no direct equivalent of 'isatty' in standard Java. There's been a RFE for something like this in the Java Bug Database since 1997, but it only has had1 one measly vote.

In theory, you might be able to implement 'isatty' using JNI magic. But that introduces all sorts of potential problems. I wouldn't even contemplate doing this myself ...


1 - Voting for Java bugs to be fixed went away around the time that Oracle took over Sun.