在 Oracle Solaris 11 控制台上 ps -ef |发出 grep java
命令我可以看到正在运行一些 java 进程 PID,它在其他控制台窗口上启动,然后它(控制台窗口)被关闭(.jar 应用程序输出然后是可见的)。是否有某种方法可以在不重新启动 .jar 文件的情况下再次获取该应用程序输出?
应用程序是这样启动的(作为 root
用户):
java -jar SomeFile.jar &
在这种情况下,将输出写入文件不是一个选项。
最佳答案
是的,你可以这样做,但它涉及到 gdb 的一些疯狂技巧。这是在 Linux 中执行此操作的方法,我相信您可以在 Solaris 中执行相同的操作(因为它具有 gdb 并且它具有我将进一步使用的所有需要的系统调用)。
标准流有 3 个文件描述符:
- 标准输入:0
- 标准输出:1
- 标准错误:2
您对 stdout 和 stderr(两者都是控制台输出)感兴趣,因此您需要带有数字 1 和 2 的文件描述符,请记住这一点。
现在我将向您展示如何为 stderr 流执行您要求的“okular”应用程序(而不是“java”应用程序)。
在终端中运行“okular”,如下所示:
$ okular &
然后关闭这个终端。这只是为了模拟您的情况。
- 打开另一个终端
寻找“okular”进程:
$ ps aux | grep okular
输出:
joe 27599 2.2 0.9 515644 73944 ? S 23:46 0:00 okular
所以“okular”PID 是27599。
查找“okular”进程的打开文件描述符:
$ ls -l /proc/27599/fd
输出:
lrwx------ 1 joe joe 64 Feb 18 23:46 0 -> /dev/pts/0 (deleted) lrwx------ 1 joe joe 64 Feb 18 23:46 1 -> /dev/pts/0 (deleted) lrwx------ 1 joe joe 64 Feb 18 23:46 2 -> /dev/pts/0 (deleted)
您会看到所有 3 个流都已删除。
现在让我们使用 gdb 附加到我们的进程:
$ gdb -p 27599 /usr/bin/okular
在 gdb 内部执行下一个操作:
(gdb) p close(2) (gdb) p creat("/tmp/okular_2", 0600) (gdb) detach (gdb) quit
这里我们调用了 2 个系统调用:
- close(),为我们进程的stderr 流关闭文件
- creat(),为我们流程的stderr 流创建新文件
p 是 gdb 命令,它打印(在我们的例子中)系统调用返回值。
现在,我们流程的所有新 stderr 输出都将附加到文本文件 /tmp/okular_2。我们可以这样不断地阅读它:
$ tail -f /tmp/okular_2
结论
好的,就是这样,我们恢复了 stderr 流。您可以对 stdout 流执行相同的操作,唯一的区别是您需要在 gdb 中调用“close(1)”而不是“close(2)”。此外,在您的情况下,请务必将所有“okular”单词替换为您的“java”单词。
大部分答案的灵感来自 this article .
如果您需要恢复stdin 流,您可以将其附加到管道(FIFO)文件,查看详情here .
关于unix - 在控制台关闭并在 Oracle Solaris 11 上打开新的控制台后,将 .jar 应用程序输出流抓取到控制台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28540045/