【问题标题】:Determining whether STDERR is going to terminal确定 STDERR 是否要终止
【发布时间】:2013-08-22 16:57:26
【问题描述】:

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

我希望在 STDERR 进入终端时显示进度条,并在 STDERR 被重定向时自动禁用自身,这样重定向数据中就不会出现各种进度条片段。

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

【问题讨论】:

标签: java linux command-line-interface stderr io-redirection


【解决方案1】:

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

【讨论】:

  • 你知道我应该查看 ioctl 中的哪个函数吗?阅读 ioctltty_ioctlconsole_ioctl 手册页后,我没有什么特别突出的。
【解决方案2】:

在将@chrylis's pointerthis answer 结合并稍作调整后,我最终得到的是:

  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");
    }
}

ant 目标生成.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

【讨论】:

  • 您不需要为此创建库(请参阅NOT INVENTED HERE)。 isatty() 已经是 glibc 二进制文件导出表的一部分,可以通过 /lib64/libc.so.6 或 /lib/lib.so.6 找到(另外,请通知@我,因为我不检查手动回答)
  • @user2284570 - 我确实使用了isatty。如果您知道如何在没有 JNI 包装器的情况下使用本机库,那么您应该告诉我们——我从未见过任何相关信息。
  • @BradMace 用户不知道他在说什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2014-04-07
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多