2013-08-20 16 views
5

Ho una suite di programmi Java che vengono utilizzati come strumenti da riga di comando sui nostri server Linux. Molti di loro usano una classe che stampa una barra di avanzamento su STDERR, simile a Term::ProgressBar di Perl.Determinare se STDERR sta per terminale

Mi piacerebbe avere la barra di avanzamento mostrata ogni volta che STDERR sta andando al terminale e si disabilita automaticamente quando STDERR viene reindirizzato in modo che non ci siano tutti i tipi di pezzi della barra di avanzamento nei dati reindirizzati.

Il controllo System.console() == null era il mio primo pensiero, ma il reindirizzamento di STDOUT è sufficiente per rendere questo true, anche se STDERR sta ancora andando al terminale. C'è qualcosa che posso controllare che sia specifico per STDERR? Una soluzione specifica per Linux o che utilizza API native sarebbe ok per le mie esigenze.

+0

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

+0

@UberDoyle I Non sto chiedendo di avviare un altro processo utilizzando Java. Voglio sapere se lo STDERR del processo * corrente * viene reindirizzato. –

risposta

1

Penso che quello che stai cercando è isatty(3), in unistd.h. Non c'è modo di sapere se un handle di file è stato reindirizzato, period, ma questo ti dirà se è ancora interattivo. Vedere la fonte per il comando tty in coreutils GNU.

+0

Sai quale funzione in ioctl dovrei guardare? Nulla spicca dopo aver letto ['ioctl'] (http://www.linuxmanpages.com/man2/ioctl.2.php), [' tty_ioctl'] (http://www.linuxmanpages.com/man4 /tty_ioctl.4.php) e ['console_ioctl'] (http://www.linuxmanpages.com/man4/console_ioctl.4.php) pagine man. –

+0

Risposta modificata dopo aver scoperto dove cercare. – chrylis

+0

@ user2284570 Sì, perché non può essere fatto in Java. Il prossimo? – chrylis

0

Dopo che unisce @chrylis's pointer con this answer e facendo un piccolo ritocco, quello che ho finalmente finito con è:

  1. creare e compilare classe Java con firma del metodo nativo
  2. uso javah per generare C file di intestazione
  3. creare il file .cpp, implementare la funzione con isatty
  4. compile codice C++ nella libreria condivisa
  5. .210
  6. esecuzione del programma Java, utilizzando -Djava.library.path=... per dire che dove la vostra libreria personalizzata è
  7. classe

Java:

package com.example.cli; 

class LinuxTerminalSupport { 

    public native boolean isStderrVisible(); 

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

bersaglio formica per generare .h:

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

file 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 (cambiamento Java include in modo da riflettere il vostro $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

Non hai bisogno di creare una libreria per questo (vedi [NON INVENTATO QUI] (https: //en.wikipedia.org/wiki/Not_invented_here # In_computing)). isatty() è già parte della tabella di esportazione dei binari di glibc e potrebbe essere trovato tramite /lib64/libc.so.6 o /lib/lib.so.6 (Inoltre, si prega di avvisare @ me come non controllo per risposte manuali) – user2284570

+0

@ user2284570 - I * ha * usato 'isatty'. Se sai come usare le librerie native senza il wrapper JNI, dovresti dircelo ... Non ho mai visto nessuna informazione in merito. –

+0

L'utente @BradMace non ha idea di cosa stia parlando. – chrylis