2013-08-20 60 views
5

Tôi có một bộ các chương trình Java được sử dụng làm công cụ dòng lệnh trên các máy chủ Linux của chúng tôi. Hầu hết trong số họ sử dụng một lớp mà in một thanh tiến trình trên STDERR, tương tự như của Perl Term::ProgressBar.Xác định xem STDERR có đang đến terminal

Tôi muốn có thanh tiến trình hiển thị bất cứ khi nào STDERR đi tới thiết bị đầu cuối và tự động vô hiệu hóa khi STDERR được chuyển hướng sao cho không có tất cả các loại thanh tiến trình trong dữ liệu được chuyển hướng.

Kiểm tra System.console() == null là suy nghĩ đầu tiên của tôi, nhưng chuyển hướng STDOUT là đủ để thực hiện điều này true, ngay cả khi STDERR vẫn đang đi đến thiết bị đầu cuối. Có bất cứ điều gì tôi có thể kiểm tra đó là cụ thể cho STDERR? Một giải pháp dành riêng cho Linux hoặc sử dụng các API gốc sẽ ổn cho các nhu cầu của tôi.

+0

http://stackoverflow.com/questions/3643939/java-process-with-input-output-stream Thưởng thức – UberDoyle

+0

@UberDoyle tôi không hỏi về việc khởi chạy một tiến trình khác bằng cách sử dụng Java. Tôi muốn biết liệu STDERR của tiến trình * current * đang được chuyển hướng hay chưa. –

Trả lời

1

Tôi nghĩ rằng những gì bạn đang tìm kiếm là isatty(3), trong unistd.h. Không có cách nào để cho biết liệu một tập tin xử lý đã được chuyển hướng, thời gian, nhưng điều đó sẽ cho bạn biết liệu nó vẫn còn tương tác. Xem mã nguồn cho lệnh tty trong lõi của GNU.

+0

Bạn có biết chức năng nào trong ioctl mà tôi nên xem không? Không có gì nổi bật với tôi sau khi đọc [ 'ioctl'] (http://www.linuxmanpages.com/man2/ioctl.2.php), [' tty_ioctl'] (http://www.linuxmanpages.com/man4 /tty_ioctl.4.php) và ['console_ioctl'] (http://www.linuxmanpages.com/man4/console_ioctl.4.php) trang người dùng. –

+0

Trả lời chỉnh sửa sau khi tôi tìm ra nơi để tìm. – chrylis

+0

@ user2284570 Vâng, bởi vì nó không thể được thực hiện trong Java. Kế tiếp? – chrylis

0

Sau khi kết hợp @chrylis's pointer với this answer và làm một chút tinh chỉnh, điều cuối cùng tôi đã kết thúc với là:

  1. tạo và biên dịch lớp Java với phương pháp chữ ký mẹ đẻ
  2. sử dụng javah để tạo ra C phần đầu tập tin
  3. tạo tệp .cpp, triển khai chức năng với isatty
  4. biên dịch mã C++ thành thư viện được chia sẻ
  5. .210
  6. chạy chương trình Java, sử dụng -Djava.library.path=... nói với nó nơi thư viện tùy chỉnh của bạn là
  7. lớp

Java:

package com.example.cli; 

class LinuxTerminalSupport { 

    public native boolean isStderrVisible(); 

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

mục tiêu kiến ​​tạo .h:

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

tập tin 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 (thay đổi java bao gồm để phản ánh của bạn $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

Bạn không cần phải tạo ra một thư viện cho điều này (xem [không phát minh ra TẠI ĐÂY] (https: //en.wikipedia.org/wiki/Not_invented_here # In_computing)). isatty() đã là một phần của bảng xuất khẩu của các mã nhị phân glibc và có thể được tìm thấy qua /lib64/libc.so.6 hoặc /lib/lib.so.6 (Ngoài ra, vui lòng thông báo cho @ me vì tôi không kiểm tra câu trả lời theo cách thủ công) – user2284570

+0

@ user2284570 - I * đã * sử dụng 'isatty'. Nếu bạn biết cách sử dụng các thư viện gốc mà không có trình bao bọc JNI thì bạn nên cho chúng tôi biết-- Tôi chưa bao giờ thấy bất kỳ thông tin nào liên quan đến điều đó. –

+0

@BradMace người dùng không có bất kỳ ý tưởng những gì anh ta nói về. – chrylis