Как я могу проверить, подключены ли потоки ввода / вывода Java-программы к терминалу?

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

  •  05-07-2019
  •  | 
  •  

Вопрос

Я бы хотел, чтобы программа Java имела разные настройки по умолчанию (детализация, возможно, цветной вывод, если поддерживается) в зависимости от ее использования.В C есть функция isatty(), которая вернет 1, если файловый дескриптор подключен к терминалу, и 0 в противном случае.Есть ли эквивалент для этого в Java?Я ничего не видел в JavaDoc для InputStream или PrintStream.

Это было полезно?

Решение

System.console () возвращает консоль, к которой подключено ваше приложение, если оно подключено, в противном случае возвращается null . (Обратите внимание, что он доступен только с JDK 6 и выше.)

Другие советы

System.console () vs isatty ()

System.console (), как уже упоминалось @Bombe, работает для простых случаев использования проверки подключения к консоли. Однако проблема с System.console () заключается в том, что он не позволяет определить, подключен ли к консоли STDIN или STDOUT (или оба, или ни один).

Разница между System.console () в Java. и isatty () C может проиллюстрировать следующую разбивку по регистру (где мы передаем данные в / из гипотетического класса Foo.class):

1) STDIN и STDOUT - это tty

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

2) STDOUT tty

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

3) STDINTTY

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

4) Ни STDIN, ни STDOUT не являются tty

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

Я не могу сказать вам, почему Java не поддерживает лучшую проверку tty. Интересно, не поддерживаются ли некоторые целевые ОС Java.

Использование JNI для вызова isatty ()

Технически, возможно сделать это в Java (как указывал stephen-c @) с некоторыми довольно простой JNI , но это сделает ваше приложение зависимым от C-кода, который может не переноситься на другие системы. Я понимаю, что некоторые люди могут не захотеть туда идти.

Краткий пример того, как будет выглядеть JNI (с большим количеством деталей):

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 (предполагает соответствие ttyutils.h ), скомпилированный в 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;
}

Другие языки:

Если у вас есть возможность использовать другой язык, я думаю, что большинство других языков поддерживают проверку tty. Но, поскольку вы задали вопрос, вы, вероятно, уже знаете это. Первое, что приходит мне на ум (кроме C / C ++), это Ruby , Python , Golang и

Краткий ответ: в стандартной Java нет прямого эквивалента 'isatty'. Существует RFE для чего-то подобного в базе данных ошибок Java, поскольку 1997, но только у было 1 одного жалкого голоса.

Теоретически вы можете реализовать isatty, используя магию JNI. Но это вводит все виды потенциальных проблем. Я бы даже не подумал сделать это сам ...

<Ч>

1 - Голосование за исправление ошибок Java ушло в то время, когда Oracle захватил Sun.

Вы можете использовать библиотеку jnr-posix для вызова собственных методов posix из Java:

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

POSIX posix = POSIXFactory.getPOSIX();

posix.isatty(FileDescriptor.out);

Если вы не хотите самостоятельно компилировать исходный код C, вы можете использовать библиотеку Jansi.Он намного меньше, чем 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) );
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top