我有一套Java程序,在我们的Linux服务器上用作命令行工具。他们中的大多数使用在STDERR上打印进度条的类,类似于Perl的Term::ProgressBar
。
我想在STDERR到达终端时显示进度条,并在重定向STDERR时自动禁用自身,以便重定向数据中没有各种进度条。< / p>
检查System.console() == null
是我的第一个想法,但是重定向STDOUT就足以使true
,即使STDERR仍在进入终端。有什么我可以检查特定于STDERR的东西吗?特定于Linux或使用本机API的解决方案可以满足我的需求。
答案 0 :(得分:1)
我认为你所寻找的是isatty(3)
,unistd.h
。没有办法判断文件句柄是否已被重定向,句点,但是它会告诉你它是否仍然是交互式的。请参阅GNU coreutils中的tty
命令的源代码。
答案 1 :(得分:0)
将@chrylis's pointer与this answer合并并进行一些调整后,我最终得到的是:
javah
生成C头文件.cpp
文件,使用isatty
-Djava.library.path=...
告诉它自定义库的位置Java类:
package com.example.cli;
class LinuxTerminalSupport {
public native boolean isStderrVisible();
static {
System.loadLibrary("term");
}
}
生成.h
的目标:
<target name="generate-native-headers">
<javah destdir="native/" verbose="yes">
<classpath refid="compile.class.path"/>
<class name="com.example.cli.LinuxTerminalSupport" />
</javah>
</target>
.cpp文件:
#include "com_example_cli_LinuxTerminalSupport.h"
#include "unistd.h"
using namespace std;
JNIEXPORT jboolean JNICALL Java_com_example_cli_LinuxTerminalSupport_isStderrVisible(JNIEnv * env, jobject obj) {
return isatty(fileno(stderr)) == 1;
}
Makefile
(更改java包含以反映您的$JAVA_HOME
):
linux: LinuxTerminalSupport.o
g++ -I/usr/java/jdk1.6.0_13/include -I/usr/java/jdk1.6.0_13/include/linux \
-o libterm.so -shared -Wl,-soname,term.so LinuxTerminalSupport.o -lc
LinuxTerminalSupport.o: LinuxTerminalSupport.cpp
g++ -c -I/usr/java/jdk1.6.0_13/include -I/usr/java/jdk1.6.0_13/include/linux LinuxTerminalSupport.cpp