如何识别向终端发送错误消息的进程?

我的终端偶尔会出现以下错误消息:

Failed to open VDPAU backend libvdpau_nvidia.so: cannot open shared object file: No such file or directory 

…这很烦人。

我在网上搜索了这个错误的解决方案,没有成功。

有没有办法至少确定负责将这些错误消息发送到终端的进程?

让我澄清一下, 据我所知 ,这些错误消息显得“出乎意料”。 实际上,它们与我与终端的交互看起来是异步的(当我回到一段无人看管的终端窗口时,我第一次看到它们)。 我确信这些消息有一个明确的,确定性的原因,但它不是我能够轻易识别出来的。 简而言之,我没有注意到它们出现的任何模式或规律性。

特别是,在我的情况下, 它们的出现与运行MPlayer或任何其他video播放程序无关。 (请参阅我之前的post 。)首先,有问题的机器是一台工作机器,我很少看到它的任何video。 在我在这台机器上观看video的极少数情况下,我使用的是VLC,而不是MPlayer,这些错误从未出现在我使用过VLC的极少数情况下。

lsof "$(tty)"通过列出您的终端打开读取或写入的内容来完成您的要求。

如果终端仍然打开,您可以检查写入终端的内容,这种情况通常是这样,至少如果它仍在运行。 它可能会向您的终端输出错误消息,关闭它的文件描述符,但仍然保持运行。 但是,您无法检查的更可能的原因是流程本身是否只是间歇性地运行。

  • jobs显示你的后台工作 。 如果您自己运行该过程并且因此它以异步方式运行 – 或者使用Ctrl + Z暂停 – 并且它仍在运行,那么内置的jobs将显示它,除非您已将其disown
  • 如果还不够, lsof "$(tty)"列出了您的终端打开以供阅读或写作的所有内容 。 这种情况甚至可以在极少数情况下写入您的终端,而不是从您的终端开始,也不是来自其他某个进程的后代。
  • 但是对于您的具体情况,我建议您阅读本答案末尾的部分,以解决该错误消息。

您可能有许多图形程序将您的终端打开以进行写入:

  • 如果您从终端运行桌面环境的主要部分(启动许多其他程序),例如Unity或其他图形shell,则会发生这种情况。
  • 特别是,如果您从终端运行了一个类似unity --replace &的命令,则可以解释出现在其中的应用程序的意外错误
  • 然后,如果您的目标是使消息静音,则应该不运行它或以不同的方式(或从不同的终端)运行它。 最好的方法取决于你运行它的原因。
  • 您可以运行pstree来查看您的进程树 ,这可能会有所帮助。

您的终端设备是“文件” ,您可以将其文件名传递给lsof

您可以通过将其设备节点的路径传递给lsof命令来获取具有当前终端的进程列表 – 运行该命令的终端 – 打开以进行读取或写入。 由于tty输出该路径,您可以运行它,然后使用它向您显示的内容运行lsof ,或者您可以使用以下任何一种方法:

 lsof "$(tty)" # "$(tty)" may expand to /dev/tty1, /dev/pts/0, /dev/pts/1, etc. 
 lsof $(tty) # bad form, but device names rarely have whitespace/globbing characters 
 lsof `tty` # same as above, just with the old disfavored backtick syntax 
 lsof /proc/$$/fd/1 # the shell expands $$ to its own process ID (fd/0, fd/1, or fd/2 work) 

输出通常看起来像这样,如果你在终端中运行的唯一程序是你的shell,当然 – lsof本身:

 lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing Output information may be incomplete. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 27763 ek 0u CHR 136,0 0t0 3 /dev/pts/0 bash 27763 ek 1u CHR 136,0 0t0 3 /dev/pts/0 bash 27763 ek 2u CHR 136,0 0t0 3 /dev/pts/0 bash 27763 ek 255u CHR 136,0 0t0 3 /dev/pts/0 lsof 29311 ek 0u CHR 136,0 0t0 3 /dev/pts/0 lsof 29311 ek 1u CHR 136,0 0t0 3 /dev/pts/0 lsof 29311 ek 2u CHR 136,0 0t0 3 /dev/pts/0 

如果您有更多的东西在读取或写入终端,则应显示它们。 请注意, 上面显示的命令必须从您看到恼人消息的终端运行 。 您也可以从单独的终端执行此操作,但是您必须为您感兴趣的终端提供lsof路径。例如,您可以在您想知道的终端中运行tty ,然后使用它向您显示的路径作为终端中lsof的参数,你想从中运行它。

关于访问权限和权限,您可能想知道:

  • tracefs警告可能会或可能不会显示给您。 无论哪种方式,你可能都不用担心 。 通常它来自调试文件系统完全不可用而不是仅限于你,所以…
  • 可能会因为sudo以root身份运行lsof而受益,但可能不会。 通常,您可以查看有关所有进程的信息,即使您的系统配置为不允许这样做,无论如何,执行此操作的任何操作都可能正在运行。

某些进程不止一次出现,因为它们会使您的终端不止一次打开。 我不建议尝试仅显示让您的终端打开以进行写入的进程,因为:

  • 当同一过程多次出现时,它们会一起显示,因此额外的条目不应该混淆。
  • 除了你从它运行的shell和程序之外,它很少见。 您通常可以使用jobs查看这些内容,每个进程可以提供一行(或更少)。 如果您使用的是lsof ,则需要详细信息。
  • 只出现一次的进程只能使您的终端打开(或仅用于读取),并且这些进程特别有意义。

一个例子:从一个终端到另一个终端。

你不必这样做 – 这真的只是一个示范。 此部分的存在仅仅是因为:

  • 您可能在lsof的输出中看不到任何可以解释您的问题的内容,并且想要某种确认,它确实向您显示写入终端的进程,即使它们不是从它启动的。
  • 您可能对其工作原理感兴趣,并希望在您控制的情况下尝试它。
  • 其他因不同原因对此主题感兴趣的读者可能需要比上一节中更多的解释,因此他们可以弄清楚如何使用它来解决他们自己的不同问题。

如果您只是在终端中运行tty ,它会打印到终端设备节点的路径:

 ek@Io:~$ tty /dev/pts/0 

这并不总是/dev/pts/0 。 您可以打开另一个终端并运行tty ,路径将不同。 来吧,做到这一点。

在第二个终端中,运行cat但将其输出重定向到第一个终端。 要做到这一点,运行此命令,但将/dev/pts/0替换为在第一个终端中运行时显示的任何tty

 cat >/dev/pts/0 

在第二个终端中键入文本,然后按Enter键它将出现在您的第一个终端中。

在第一个终端中,运行上面显示的任何lsof命令。

 ek@Io:~$ lsof "$(tty)" lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing Output information may be incomplete. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 27763 ek 0u CHR 136,0 0t0 3 /dev/pts/0 bash 27763 ek 1u CHR 136,0 0t0 3 /dev/pts/0 bash 27763 ek 2u CHR 136,0 0t0 3 /dev/pts/0 bash 27763 ek 255u CHR 136,0 0t0 3 /dev/pts/0 cat 29476 ek 1w CHR 136,0 0t0 3 /dev/pts/0 lsof 29479 ek 0u CHR 136,0 0t0 3 /dev/pts/0 lsof 29479 ek 1u CHR 136,0 0t0 3 /dev/pts/0 lsof 29479 ek 2u CHR 136,0 0t0 3 /dev/pts/0 

您的终端不会突出显示与cat的线 – 我只是这样做以显示差异。

(在cat运行的第二个终端中,您可以通过在行的开头按Ctrl + D退出它,或者只需按Ctrl + C退出。如果您在一行上键入文本然后按Ctrl + D ,那将即使您没有按Enter键也刷新输入缓冲区,您将在第一个终端上看到文本。)

调试“无法打开VDPAU后端”错误

虽然这是一个关于如何找到写入终端的问题的一般答案,它可能对您有所帮助,但您还应该考虑其他方法,针对您在此处描述的特定问题。 除了虚拟控制台上的内核消息 – 这不是 – 终端中显示的消息通常来自您从终端运行的某个程序,或者其中一个程序运行的程序等。

正如NickTh的回答所说,如果你没有从你的终端手动运行任何看起来可以产生这些消息的东西,请检查你的shell在启动时可以运行命令的文件 ,特别是.profile.bashrc (如NickTh所提到的 )因为那些是你可能修改过的那些。

你看到的错误可能不是MPlayer本身的错误,而是在它使用的库中,这是许多其他程序使用的。 如果您正在从终端运行任何图形程序 – 特别是如果您使用&将它们放在后台,因此它们与您的shell异步运行 – 那么它们中的一个或多个几乎肯定是您看到这些消息的原因。 Web浏览器特别容易生成它们,主要是因为它们可能运行使用受影响的库的插件,例如Adobe Flash。

Launchpad上报告了许多关于此类错误消息的错误。 Bug 808254与您所描述的特别相似。 Bug 1300215尤其突出,但涉及英特尔video驱动程序。 您可以在Launchpad中搜索消息中的文本以查找更多错误。 在这样的错误报告及其评论中,您可能会找到解决方法 – 无论是用于消息消息还是用于处理有关错误的更多信息。 此外,虽然与NickTh的答案相关的另一个问题是关于问题,它发生在MPlayer中,并且有几个MPlayer特定的解决方法作为答案, 目前最高投票的答案并不特定于MPlayer,可能对你有用。

如果您从终端运行许多程序,则可能在lsof的输出中看到了许多条目(如果您决定在故障排除中使用该方法)。 确定哪个程序产生输出的一种方法是从不同的终端运行程序。 即使您的单独终端彼此启动这也是有效的 – 像GNOME终端这样的GUI终端模拟器不会将错误消息或其他显示的文本传递给它自己运行的终端(如果有的话)。 同样,一种不受此问题困扰的方法 – 假设烦人的消息是唯一真正的问题 – 就是不要从你的终端运行你不想在终端输出的东西。 通常,您可以通过使用图形菜单来实现此目的。 但请查看此答案的顶部,了解为什么您可能从您的终端运行更多,而不是您需要或打算。

通常,终端中的错误消息不会自行显示。 你必须运行一些东西,这个东西必须失败,这样的消息就会出现。 例如,请参阅此问答: GNOME Mplayer:“无法打开VDPAU后端libvdpau_nvidia.so”错误

那么你在终端内运行的应用程序是什么产生了这样的错误?

如果在打开终端时出现此消息,请查看是否在.bashrc文件或.profile文件中添加了一些内容。

在类似情况下对我有用的解决方法是创建一个链接,如上面的答案(链接I给出)中所述。