Comment puis-je vérifier si les flux d'entrée / sortie d'un programme Java sont connectés à un terminal?

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

  •  05-07-2019
  •  | 
  •  

Question

Je voudrais qu'un programme Java ait des paramètres par défaut différents (verbosité, éventuellement sortie en couleur lorsque celle-ci est supportée) en fonction de son utilisation. En C, il existe une fonction isatty () qui renvoie 1 si un descripteur de fichier est connecté à un terminal et 0 sinon. Existe-t-il un équivalent pour cela en Java? Je n'ai rien vu dans JavaDoc pour InputStream ou PrintStream.

Était-ce utile?

La solution

System.console () renverra la console à laquelle votre application est connectée si elle est connectée, sinon elle renvoie null . (Notez qu’il est uniquement disponible à partir de la version 6 du JDK.)

Autres conseils

System.console () vs isatty ()

System.console (), comme déjà mentionné par @Bombe, fonctionne pour des cas simples d'utilisation de la vérification de la connexion à la console. Le problème avec System.console (), cependant, est qu’il ne vous permet pas de déterminer si c’est STDIN ou STDOUT (ou les deux, ni aucun) qui est connecté à une console.

Différence entre System.console () de Java. et le isatty () de C peut être illustrée dans la répartition de cas suivante (où nous canalisons les données vers / depuis une classe Foo.cloth hypothétique):

1) STDIN et STDOUT sont des tty

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

2) STDOUT est tty

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

3) STDIN est tty

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

4) Ni STDIN ni STDOUT ne sont des tty

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

Je ne peux pas vous dire pourquoi Java ne prend pas en charge un meilleur contrôle des tickets. Je me demande si certains systèmes d'exploitation cibles de Java ne la prennent pas en charge.

Utiliser JNI pour appeler isatty ()

Il est techniquement possible de le faire en Java (comme l'a souligné stephen-c @) avec certains JNI assez simple , mais votre application dépendra du code C qui peut ne pas être portable sur d’autres systèmes. Je peux comprendre que certaines personnes puissent ne pas vouloir y aller.

Un exemple rapide de ce à quoi ressemblerait l'interface JNI (survolant de nombreux détails):

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 (en supposant que ttyutils.h correspond ), compilé dans 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;
}

Autres langues:

Si vous avez la possibilité d’utiliser une autre langue, la plupart des autres langues sont compatibles avec la vérification des tickets. Mais, puisque vous avez posé la question, vous le savez probablement déjà. Les premiers qui me viennent à l’esprit (à part le C / C ++) sont Ruby , Python , Golang et Perl .

La réponse courte est qu’il n’existe pas d’équivalent direct de "isatty" en Java standard. Il y a eu un RFE dans la base de données de bogues Java depuis 1997, mais seul a à 1 un seul maigre vote.

En théorie, vous pourrez peut-être implémenter «isatty» en utilisant la magie JNI. Mais cela introduit toutes sortes de problèmes potentiels. Je n’envisagerais même pas de le faire moi-même ...

1 - Le vote sur les bogues Java à réparer a disparu à peu près au moment où Oracle a repris Sun.

Vous pouvez utiliser la bibliothèque jnr-posix pour appeler les méthodes posix natives. de Java:

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

POSIX posix = POSIXFactory.getPOSIX();

posix.isatty(FileDescriptor.out);

Si vous ne voulez pas compiler vous-même la source C, vous pouvez utiliser la bibliothèque Jansi. C'est beaucoup plus petit que jnr-posix

<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) );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top