5

我有一套 Java 程序,它们在我们的 Linux 服务器上用作命令行工具。他们中的大多数使用一个在 STDERR 上打印进度条的类,类似于 Perl 的Term::ProgressBar.

我希望在 STDERR 进入终端时显示进度条,并在重定向 STDERR 时自动禁用自身,以便重定向数据中没有各种进度条。

检查System.console() == null是我的第一个想法,但重定向 STDOUT 就足以做到这一点true,即使 STDERR 仍在终端。有什么我可以检查的特定于 STDERR 的吗?特定于 Linux 或使用本机 API 的解决方案可以满足我的需求。

4

2 回答 2

1

我想你正在寻找的是isatty(3),在unistd.h。没有办法判断文件句柄是否已被重定向,句号,但这会告诉你它是否仍然是交互式的。tty请参阅GNU coreutils中命令的源代码。

于 2013-08-20T15:17:53.030 回答
0

在将@chrylis 的指针这个答案结合起来并进行一些调整之后,我最终得到的是:

  1. 使用本机方法签名创建和编译 Java 类
  2. 用于javah生成C头文件
  3. 创建.cpp文件,实现功能isatty
  4. 将 C++ 代码编译成共享库
  5. 运行 Java 程序,-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
于 2013-08-22T03:27:59.573 回答