unix - 在控制台关闭并在 Oracle Solaris 11 上打开新的控制台后,将 .jar 应用程序输出流抓取到控制台

标签 unix console solaris

在 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(两者都是控制台输出)感兴趣,因此您需要带有数字 12 的文件描述符,请记住这一点。

现在我将向您展示如何为 stderr 流执行您要求的“okular”应用程序(而不是“java”应用程序)。

  1. 在终端中运行“okular”,如下所示:

    $ okular &
    

    然后关闭这个终端。这只是为了模拟您的情况。

  2. 打开另一个终端
  3. 寻找“okular”进程:

    $ ps aux | grep okular
    

    输出:

    joe      27599  2.2  0.9 515644 73944 ?        S    23:46   0:00 okular
    

    所以“okular”PID 是27599

  4. 查找“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 个流都已删除。

  5. 现在让我们使用 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 命令,它打印(在我们的例子中)系统调用返回值。

  6. 现在,我们流程的所有新 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/

相关文章:

java - 如何检测Unix终端字符编码?

bash - 在 Solaris 上的 awk 中使用多字符字段分隔符

unix - 如何在 Heroku 中运行 Meteor shell?

使用 C unix 命令或 C 更改文件中的特定单词

ruby-on-rails - Rails 控制台困惑

c++ - Solaris 10 CC 预处理器错误导致 undefined symbol

perl - 计算包含数十万个文件的目录中文件数量的最快方法

python - 限制脚本的 CPU 使用率

python - 在 Mac 上将文件复制到 RAM (Python)

windows - 让CreateProcess继承调用进程的控制台