附加到进程输出以供查看

Posted

技术标签:

【中文标题】附加到进程输出以供查看【英文标题】:Attach to a processes output for viewing 【发布时间】:2010-10-17 11:25:38 【问题描述】:

如何将控制台/终端视图“附加”到应用程序输出,以便查看它可能在说什么?

如何在不终止应用程序的情况下从应用程序输出中分离?

通常,如果您使用命令行启动一个健谈的应用程序,您会看到各种精彩的输出。但是,假设我正在运行一个特别健谈的程序,比如 KINO,我想在任何给定时刻查看它的输出,而无需通过命令行重新启动它。我不能;至少我不知道怎么做。

【问题讨论】:

您的进程中有调试符号吗?它在生产环境中运行吗?如果是这样,您是否需要它永远不会被暂停? 当我遇到 kino 等最终用户程序的稳定性问题(崩溃并杀死我的声音)时,我希望能够知道它是如何/为什么崩溃的,以便我可以修复它。这不是我正在开发的程序,而是我想知道的故障排除技术。我会在下面尝试你的建议。 【参考方案1】:

我想我在这里有一个更简单的解决方案。只需在/proc 路径下可访问的伪文件系统下查找名称与您要查找的PID 对应的目录。所以如果你有一个程序正在运行,它的 ID 是 1199,cd 进入它:

$ cd /proc/1199

然后寻找下面的fd目录

$ cd fd

这个fd 目录包含你的程序正在使用的文件描述符对象(0:stdin,1:stdout,2:stderr)和你需要的 tail -f ——在这种情况下,stdout):

$ tail -f 1

【讨论】:

我无法使用tail,因为在我的情况下,输出被重定向到另一个进程进行输入,但more 向我显示了当前数据。 本网站上最引人入胜的帖子之一! more 正在为我工​​作。节点进程上的 ubuntu 14.04 这不适用于调用 System.out.println 的 java 进程。 /proc/[pid]/fd/1 根本没有输出 尝试使用以下创建复制,但无济于事:``` docker run -it --name container1 ubuntu bash -c -i "COUNT=0; while true; do echo Keep舞池节拍; ((COUNT++)); sleep 1; echo \"Count is: \$COUNT\"; done;" ``` 在另一个终端: ``` docker exec -it container1 tail -f /proc/1/fd/1 ```【参考方案2】:

我一直在寻找同样的东西,发现你可以做到:

strace -ewrite -p $PID

这不是您所需要的,但已经非常接近了。

我尝试了重定向输出,但这对我不起作用。 可能是因为进程正在写入套接字,我不知道。

【讨论】:

感谢它的工作,但输出被截断,例如for ping: write(1, "64 bytes from 1.0.0.1: icmp_seq="..., 56) = 56 @izy 您可以指定-sLENGTH 标志来设置新的缓冲区大小(默认为 32)。更多详情,请查看unix.stackexchange.com/a/58601【参考方案3】:

这里有几个选项。一种是将命令的输出重定向到一个文件,然后使用 'tail' 实时查看添加到该文件的新行。

另一种选择是在“屏幕”内启动您的程序,这是一种基于文本的终端应用程序。屏幕会话可以附加和分离,但名义上只能由同一用户使用,所以如果你想在用户之间共享它们,那就太麻烦了。

【讨论】:

"这里有几个选项。一个是将命令的输出重定向到一个文件,然后使用'tail'实时查看添加到该文件的新行。"这可以用已经运行的应用程序完成吗? 您可能需要 tail -f $log_file 来获取写入文件中的输出。另外,不,我不知道如何使用已经运行的应用程序来做到这一点。 @aggitan:不。对于现有应用程序,您必须重新启动它们,因为它们已经将 I/O 绑定到控制终端。 见unix.stackexchange.com/questions/31824/…【参考方案4】:

对我来说,这很有效:

    以进程所有者身份登录(即使root被拒绝权限)

    ~$ su - process_owner
    

    在许多其他答案中提到文件描述符。

    ~$ tail -f /proc/<process-id>/fd/1 # (0: stdin, 1: stdout, 2: stderr)
    

【讨论】:

如果文件描述符指向一个套接字怎么办? # ls -la /proc/24510/fd/1 lrwx------ 1 root root 64 Oct 31 08:34 /proc/24510/fd/1 -&gt; socket:[444026]【参考方案5】:

你可以使用reptyr:

sudo apt install reptyr
reptyr pid

【讨论】:

如果reptyr $PID 不起作用,请根据issue 尝试sudo reptyr -T $PID【参考方案6】:

我将如何“附加”一个 控制台/终端视图到 应用程序输出,所以我可以看到什么 它可能会说?

关于这个问题,我知道即使您在启动进程之前没有启动 sceen 命令,也可以捕获输出。

虽然我从未尝试过,但我发现了一篇有趣的文章,它解释了如何使用 GDB(并且无需重新启动进程)。

redirecting-output-from-a-running-process

基本上:

    感谢/proc/xxx/fd,检查您的进程的打开文件列表 附加您的流程与 GDB 暂停时,关闭您感兴趣的文件,调用 close() 函数(您可以在 GDB 中使用您的进程的任何函数。我怀疑您的进程中需要调试符号.. ) 调用 create() 或 open() 函数打开一个新文件。 (看看最后的 cmets,你会看到人们建议使用 dup2() 以确保使用相同的句柄) 分离进程并让其运行。

顺便说一句,如果您在 i386 机器上运行 linux 操作系统,cmets 正在讨论一种更好的工具来将输出重定向到新控制台:'retty' .如果是这样,请考虑使用它。

【讨论】:

【参考方案7】:

我想远程观看在本地运行的 yum 升级过程,所以虽然可能有更有效的方法可以做到这一点,但我是这样做的:

watch cat /dev/vcsa1

显然你会想要使用 vcsa2、vcsa3 等,具体取决于所使用的终端。

只要我的终端窗口与运行命令的终端宽度相同,我就可以每两秒看到它们当前输出的快照。其他地方推荐的其他命令在我的情况下效果不佳,但那个成功了。

【讨论】:

以上是关于附加到进程输出以供查看的主要内容,如果未能解决你的问题,请参考以下文章

附加到正在运行的 Windows 进程

C#:以干净的方式将调试器附加到进程

如何将跟踪侦听器附加到正在运行的进程?

“无法打开文件以供阅读”将PDF从存储附加到可邮寄

Android Studio 附加到进程未找到本机符号

使用 jQuery 加载图像并将其附加到 DOM