【问题标题】:How do I get java to exit when piped to head管道传输到head时如何让java退出
【发布时间】:2012-07-26 14:04:18
【问题描述】:

我有一个打印出大量文本的 java 进程。有时我只想看一点文字。使用普通程序我可以做到:

$ myprog | head

我只会看到 myprog 的 10 行输出,它会立即退出。但是对于 java,如果我这样做:

$ java MyClass | head

我得到了前 10 行输出,但 java 进程在完成所有处理之前不会退出。这就像java不在乎stdout(System.out)已经消失了,head进程已经死了。

所有其他程序要么静默退出,比如 cat:

$ cat /etc/group | head
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:

或以损坏的管道错误/异常退出,例如 python:

$ python -c 'while True: print "hi"' | head
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
Traceback (most recent call last):
  File "<string>", line 1, in <module>
IOError: [Errno 32] Broken pipe

当我将输出通过管道传输到诸如 head 之类的东西时,如何在调用 System.out.println() 时让 java 引发异常?我希望能够做类似的事情:

try {
    while(true) {
        System.out.println("hi");
    }
} catch(BrokenPipeException e) {
    // exit gracefully
}

【问题讨论】:

  • SIGPIPE 在这种情况下被发送到 java 进程,但我不确定 java 用它做什么。如果您可以检查 JVM 是否已收到 sigpipe 并死亡,它应该可以工作。
  • Java 对信号做了一些特殊的事情,我从其他问题中知道,几乎不可能将 java 程序设置为捕获信号。

标签: java exception pipe unix-head


【解决方案1】:

我正在使用checkError()

来自PrintStream-API-Docu

与其他输出流不同,PrintStream 从不抛出 异常;相反,特殊情况只是设置了一个内部 可以通过 checkError 方法测试的标志。

所以尝试这样的事情:

        while(!System.out.checkError()) {
            System.out.println("hi");
        }

【讨论】:

  • 感谢您对文档的关注。我一直在到处寻找类似的东西,但由于某种原因,它掩盖了顶级描述。这太烦人了,而且每次都调用 checkError 而不是 try-catch 似乎效率低下。
【解决方案2】:

如果您不喜欢 Sascha's answer 中的 .checkError() 方法并且希望收到异常,您可以使用

OutputStream stream = new FileOutputStream(FileDescriptor.out);

您失去了PrintStream 的特定功能。就我而言,它们并不相关,而且这种方法比构建一堆 hacky 检查更容易。

请注意,如果您通过 System.setOut 重定向了 System.out,这将不会起作用,因为 FileDescriptor.out 将指向原始输出描述符,而不是您重定向的描述符。

【讨论】:

    猜你喜欢
    • 2011-02-20
    • 2012-09-02
    • 1970-01-01
    • 2016-04-18
    • 2016-03-16
    • 2011-03-21
    • 2018-05-27
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多