System.console() 与 isatty()
正如 @Bombe 已经提到的,System.console() 适用于检查控制台连接性的简单用例。然而,System.console() 的问题是,它不允许您确定连接到控制台的是 STDIN 还是 STDOUT(或两者或两者都不是)。
Java 的区别系统.控制台() http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#console%28%29和C的isatty() http://man7.org/linux/man-pages/man3/isatty.3.html%20%22isatty%28%29可以通过以下案例分解来说明(我们通过管道将数据传入/传出假设的 Foo.class):
1) STDIN 和 STDOUT 是 tty
%> java Foo
System.console() => <Console instance>
isatty(STDIN_FILENO) => 1
isatty(STDOUT_FILENO) => 1
2)标准输出是tty
%> echo foo | java Foo
System.console() => null
isatty(STDIN_FILENO) => 0
isatty(STDOUT_FILENO) => 1
3) STDIN 是 tty
%> 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()
从技术上来说is可以在Java中使用一些方法来做到这一点(正如stephen-c@指出的)相当简单的 JNI http://jonisalonen.com/2012/calling-c-from-java-is-easy/,但它会使您的应用程序依赖于可能无法移植到其他系统的 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 http://www.ruby-doc.org/core-2.1.1/IO.html#method-i-tty-3F, Python https://docs.python.org/2/library/os.html#os.isatty, Golang http://godoc.org/code.google.com/p/go.crypto/ssh/terminal#IsTerminal and Perl http://perldoc.perl.org/POSIX.html#isatty.