Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 确定STDERR是否将要连接到终端_Java_Linux_Command Line Interface_Stderr_Io Redirection - Fatal编程技术网

Java 确定STDERR是否将要连接到终端

Java 确定STDERR是否将要连接到终端,java,linux,command-line-interface,stderr,io-redirection,Java,Linux,Command Line Interface,Stderr,Io Redirection,我有一套Java程序,在我们的Linux服务器上用作命令行工具。它们中的大多数使用在STDERR上打印进度条的类,类似于Perl的Term::ProgressBar 我希望在STDERR进入终端时显示进度条,并在STDERR被重定向时自动禁用进度条,这样重定向的数据中就不会有各种各样的进度条了 检查System.console()==null是我的第一个想法,但是重定向STDOUT就足以使这成为真的,即使STDERR仍将到达终端。有什么我可以检查的是特定于STDERR的吗?一个特定于Linux或

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

我希望在STDERR进入终端时显示进度条,并在STDERR被重定向时自动禁用进度条,这样重定向的数据中就不会有各种各样的进度条了


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

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

在结合并进行了一些调整后,我最终得到的是:

  • 使用本机方法签名创建和编译Java类
  • 使用
    javah
    生成C头文件
  • 创建
    .cpp
    文件,使用
    isatty实现函数
  • 将C++代码编译为共享库
  • 运行Java程序,使用
    -Djava.library.path=…
    告诉它自定义库在哪里
  • Java类:

    package com.example.cli;
    
    class LinuxTerminalSupport {
    
        public native boolean isStderrVisible();
    
        static {
            System.loadLibrary("term");
        }
    }
    
    要生成
    .h
    的ant目标:

    <target name="generate-native-headers">
        <javah destdir="native/" verbose="yes">
            <classpath refid="compile.class.path"/>
            <class name="com.example.cli.LinuxTerminalSupport" />
        </javah>
    </target>
    
    Makefile
    (更改java包含以反映您的
    $java\u主页
    ):


    Enjoy@UberDoyle我不是在问使用Java启动另一个进程。我想知道当前进程的STDERR是否被重定向。你知道我应该查看ioctl中的哪个函数吗?在阅读了、和手册页之后,我觉得没有什么突出的地方。您不需要为此创建库(请参阅)。isatty()已经是glibc二进制文件导出表的一部分,可以通过/lib64/libc.so.6或/lib/lib.so.6找到(另外,请通知@me,因为我没有手动检查答案)@user2284570-我确实使用了
    isatty
    。如果您知道如何在没有JNI包装器的情况下使用本机库,那么您应该告诉我们——我从未见过任何与此相关的信息。@BradMace用户不知道他在说什么。
    #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;
    }
    
    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