2013-08-20 3 views
5

Ich habe eine Reihe von Java-Programmen, die als Kommandozeilen-Tools auf unseren Linux-Servern verwendet werden. Die meisten von ihnen verwenden eine Klasse, die eine Fortschrittsleiste auf STDERR druckt, ähnlich wie Perls Term::ProgressBar.Ermitteln, ob STDERR zum Terminal geht

Ich mag würde der Fortschrittsbalken angezeigt haben, wenn STDERR an das Terminal wird und sich automatisch abschalten, wenn STDERR umgeleitet wird, so dass es nicht alle Arten von Fortschrittsbalken Stücke in den umgeleiteten Daten sind.

Die Überprüfung System.console() == null war mein erster Gedanke, aber Umleitung STDOUT ist genug, um diese true zu machen, auch wenn STDERR noch zum Terminal geht. Gibt es etwas, das ich überprüfen kann, das spezifisch für STDERR ist? Eine Lösung, die Linux-spezifisch ist oder native APIs verwendet, wäre für meine Bedürfnisse in Ordnung.

+0

http://stackoverflow.com/questions/3643939/java-process-with-input-output-stream Genießen – UberDoyle

+0

@UberDoyle I Ich möchte nicht einen anderen Prozess mit Java starten. Ich möchte wissen, ob der STDERR des * aktuellen * Prozesses umgeleitet wird. –

Antwort

1

Ich denke, was Sie suchen, ist isatty(3), in unistd.h. Es gibt keine Möglichkeit zu sagen, ob ein Datei-Handle umgeleitet wurde, Punkt, aber das sagt Ihnen, ob es noch interaktiv ist. Siehe die Quelle für den tty Befehl in GNU Coreutils.

+0

Wissen Sie, welche Funktion in ioctl ich betrachten sollte? Nichts fällt mir nach dem Lesen der ['ioctl] (http://www.linuxmanpages.com/man2/ioctl.2.php), [' tty_ioctl'] (http://www.linuxmanpages.com/man4) auf /tty_ioctl.4.php) und ['console_ioctl'] (http://www.linuxmanpages.com/man4/console_ioctl.4.php) man-Seiten. –

+0

Antwort bearbeitet, nachdem ich herausgefunden habe, wo ich suchen soll. – chrylis

+0

@ user2284570 Ja, weil es nicht in Java gemacht werden kann. Nächster? – chrylis

0

Nach @chrylis's pointer mit this answer kombiniert und ein wenig Gefummel zu tun, was ich am Ende schließlich mit ist:

  1. erstellen und Java-Klasse mit nativen Methodensignatur kompilieren
  2. Verwendung javah C-Header-Datei
  3. zu erzeugen
  4. erstellen .cpp Datei, Implementierung Funktion mit isatty
  5. Kompilierung C++ Code in gemeinsam genutzten Bibliothek
  6. laufen Java-Programm, mit -Djava.library.path=... ihm zu sagen, wo Ihre benutzerdefinierten Bibliothek

Java-Klasse ist:

package com.example.cli; 

class LinuxTerminalSupport { 

    public native boolean isStderrVisible(); 

    static { 
     System.loadLibrary("term"); 
    } 
} 

ant Ziel .h zu generieren:

<target name="generate-native-headers"> 
    <javah destdir="native/" verbose="yes"> 
     <classpath refid="compile.class.path"/> 
     <class name="com.example.cli.LinuxTerminalSupport" /> 
    </javah> 
</target> 

CPP-Datei:

#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 (ändern java enthält Ihre $JAVA_HOME zu reflektieren):

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

Sie mussten dafür keine Bibliothek erstellen (siehe [HIER NICHT ERFUNDEN] (https: //en.wikipedia.org/wiki/Not_invented_here # In_computing)). isatty() ist bereits Teil der Exporttabelle der glibc-Binärdateien und könnte über /lib64/libc.so.6 oder /lib/lib.so.6 gefunden werden (Bitte teilen Sie @me auch mit, wenn ich nicht nachsehen möchte Antworten manuell) – user2284570

+0

@ user2284570 - Ich habe '' '' '' verwendet. Wenn Sie wissen, wie Sie native Bibliotheken ohne den JNI-Wrapper verwenden, sollten Sie uns Folgendes sagen: Ich habe noch nie Informationen darüber gesehen. –

+0

@BradMace Benutzer hat keine Ahnung worüber er spricht. – chrylis

Verwandte Themen