2013-08-20 52 views
5

我有一套Java程序,在我們的Linux服務器上用作命令行工具。他們中的大多數使用在STDERR上打印進度條的類,類似於Perl的Term::ProgressBar確定STDERR是否要去終端

我希望每當STDERR進入終端時都會顯示進度條,並且在重定向STDERR時自動禁用自身,以便在重定向數據中沒有任何種類的進度條。

檢查System.console() == null是我的第一個想法,但重定向STDOUT足以使此true,即使STDERR仍然要去終端。有什麼我可以檢查特定於STDERR的嗎?特定於Linux的解決方案或使用本機API的解決方案可以滿足我的需求。

+0

http://stackoverflow.com/questions/3643939/java-process-with-input-output-stream 享受 – UberDoyle

+0

@UberDoyle我我不問有關使用Java啓動另一個進程的問題。我想知道* current *進程的STDERR是否被重定向。 –

回答

1

我認爲你要找的是isatty(3),在unistd.h。無法確定文件句柄是否已重定向,句點,但會告訴您它是否仍然是交互式的。在GNU coreutils中查看tty命令的源代碼。

+0

你知道ioctl中我應該看哪個函數嗎?讀完[ioctl'](http://www.linuxmanpages.com/man2/ioctl.2.php),['tty_ioctl'](http://www.linuxmanpages.com/man4)後, /tty_ioctl.4.php)和['console_ioctl'](http://www.linuxmanpages.com/man4/console_ioctl.4.php)手冊頁。 –

+0

答案編輯後,我想出了在哪裏看。 – chrylis

+0

@ user2284570是的,因爲它不能在Java中完成。下一個? – chrylis

0

this answer結合@chrylis's pointer並做了一點調整,我終於結束了之後是:

  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 
+0

你不需要爲此創建一個庫(參見[NOT INVENTED HERE](https://en.wikipedia)。組織/維基/ Not_invented_here#In_computing))。 isatty()已經是glibc二進制文件的導出表的一部分,可以通過/lib64/libc.so.6或/lib/lib.so.6找到(另外,請通知@我,因爲我沒有檢查手動回答) – user2284570

+0

@ user2284570 - 我*使用'isatty'。如果你知道如何在沒有JNI包裝的情況下使用本地庫,那麼你應該告訴我們 - 我從來沒有見過有關這方面的任何信息。 –

+0

@BradMace用戶不知道他在說什麼。 – chrylis

相關問題