Wie kann ich überprüfen, ob die Eingangs-/Ausgabestreams eines Java -Programms mit einem Terminal verbunden sind?

StackOverflow https://stackoverflow.com/questions/1403772

  •  05-07-2019
  •  | 
  •  

Frage

Ich möchte, dass ein Java -Programm je nach Verwendung unterschiedliche Standardeinstellungen (Ausführlichkeit, möglicherweise farbige Ausgabe) hat. In C gibt es eine Isatty () -Funktion, die 1 zurückgibt, wenn ein Dateideskriptor mit einem Terminal verbunden ist, und ansonsten 0. Gibt es ein Äquivalent dafür in Java? Ich habe im Javadoc für InputStream oder Printstream nichts gesehen.

War es hilfreich?

Lösung

System.Console () Gibt die Konsole zurück, an die Ihre Anwendung angeschlossen ist, wenn sie angeschlossen ist. Andernfalls kehrt sie zurück null. (Beachten Sie, dass es nur bei JDK 6 erhältlich ist.)

Andere Tipps

System.Console () gegen Isatty ()

System.Console (), wie bereits von @Bombe erwähnt, arbeitet für einfache Anwendungsfälle für die Überprüfung der Konsolenverbindlichkeit. Das Problem mit System.Console () ist jedoch, dass Sie nicht feststellen können, ob es sich um Stdin oder Stdout (oder beides oder auch nicht) handelt, die mit einer Konsole verbunden sind.

Der Unterschied zwischen Javas System.Console () und c's isatty () kann im folgenden Fall-Ausbruch veranschaulicht werden (wo wir Daten zu/von einer hypothetischen Foo.class leiten):

1) Stdin und Stdout sind tty

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

2) stdout ist tty

%> echo foo | java Foo
System.console() => null
isatty(STDIN_FILENO) => 0
isatty(STDOUT_FILENO) => 1

3) stdin ist tty

%> java Foo | cat
System.console() => null
isatty(STDIN_FILENO) => 1
isatty(STDOUT_FILENO) => 0

4) Weder Stdin noch Stdout sind tty

%> echo foo | java Foo | cat
System.console() => null
isatty(STDIN_FILENO) => 0
isatty(STDOUT_FILENO) => 0

Ich kann Ihnen nicht sagen, warum Java bessere Tty-Checking unterstützt. Ich frage mich, ob einige von Javas Target OS es nicht unterstützen.

Verwenden Sie JNI, um Isatty () anzurufen

Es technisch gesehen ist möglich, dies in Java (wie Stephen-C@ betonte) mit einigen zu tun ziemlich einfach jni, Aber es wird Ihre Anwendung von C-Code abhängen, die möglicherweise nicht für andere Systeme tragbar ist. Ich kann verstehen, dass einige Leute möglicherweise nicht dorthin gehen wollen.

Ein kurzes Beispiel dafür, wie der JNI aussehen würde (um viele Details zu beschönigen):

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: tyutils.c (Angenommen Matching tyutils.h), zusammengestellt zu 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;
}

Andere Sprachen:

Wenn Sie die Möglichkeit haben, eine andere Sprache zu verwenden, kann ich mir die meisten anderen Sprachen vorstellen, um TTY-Checking zu unterstützen. Aber da Sie die Frage gestellt haben, wissen Sie das wahrscheinlich schon. Das erste, das mir in den Sinn kommt (abgesehen von C/C ++), sind Rubin, Python, Golang und Perl.

Die kurze Antwort ist, dass es in Standard -Java kein direktes Äquivalent zu "Isatty" gibt. Es gab eine RFE für so etwas in der Java -Fehler -Datenbank seit 1997, aber nur es hat hatte1 eine masliche Abstimmung.

Theoretisch können Sie in der Lage sein, "Isatty" mit JNI -Magie zu implementieren. Das führt jedoch alle möglichen potenziellen Probleme ein. Ich würde nicht einmal darüber nachdenken, dies selbst zu tun ...


1 - Die Abstimmung über die Reparatur von Java -Bugs ging ungefähr zu der Zeit, als Oracle die Sonne übernahm.

Du könntest benutzen jnr-poxsix Bibliothek, um native POSIX -Methoden von Java aufzurufen:

import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import java.io.FileDescriptor;

POSIX posix = POSIXFactory.getPOSIX();

posix.isatty(FileDescriptor.out);

Wenn Sie C nicht selbst kompilieren möchten, können Sie die Jansi -Bibliothek verwenden. Es ist viel kleiner als JNR-Poxex

<dependency>
  <groupId>org.fusesource.jansi</groupId>
  <artifactId>jansi</artifactId>
  <version>1.17.1</version>
</dependency>

...

import static org.fusesource.jansi.internal.CLibrary.isatty;

...

System.out.println( isatty(STDIN_FILENO) );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top