如果从终端启动应用程序,您可以看到 stdout 和 stderr 的输出,但如果从窗口管理器启动应用程序,这些文件的输出通常会去哪里?到/dev/null?
答案1
从窗口管理器启动的应用程序的输出与窗口管理器本身的输出位于同一位置。 (除非应用程序重定向它,但典型的 GUI 应用程序不会。)
您可以通过查看文件描述符 1(标准输出)和文件描述符 2(标准错误)上打开的内容来找出 WM 的输出去向;通常两者都会转到同一个文件。找出您的窗口管理器的进程 ID(例如尝试pgrep metacity
或如果 Metacity 是您的窗口管理器 — 如果您不知道窗口管理器的进程名称,请查看或pidof metacity
报告的进程树之一的根)。假设你的窗口管理器的进程ID是1234,运行ps f
pstree
lsof -p1234
并查找与文件描述符 1 和 2 对应的行,或者
或者
ls -l /proc/1234/fd
您可以自动过滤相关文件描述符:
lsof -p1234 | awk '$4 ~ /^[12][^0-9]/'
ls -l /proc/1234/fd/[12]
(注:以上所有命令均适用于 Linux。pgrep
在其他 unice 中很常见,并且lsof
几乎可以安装在任何地方;不同 unice 的ps
选项和/proc
内容有所不同。)
在常见情况下,您从在终端模拟器(xterm、konsole、gnome-terminal 等,但不是跨屏幕或 tmux 使用时)中运行的 shell 运行命令,那么您可以轻松检查终端模拟器的输出位置正在进行,因为终端模拟器是 shell 的父进程。如果终端仿真器以附加权限运行,则此方法不起作用,某些系统上会发生这种情况,以允许终端仿真器写入登录用户列表 (utmp)。
lsof -p$PPID
ls -l /proc/$PPID/fd
许多发行版将 X 会话的输出定向到~/.xsession-errors
.
答案2
窗口管理器是 X 服务器的子级,因此它及其子级的输出与 X 服务器位于同一位置。
如果您是唯一的用户并且以图形方式登录,某些系统会从输出控制台替换 X 服务器实例,这意味着您可以切换到那个VT并看到它。有趣的是,这种安排通常是alt-ctrl-f1
X 实例的输出控制台,也是alt-ctrl-f7
X 显示器,但您可以检查尽可能多的内容。前 6 个通常会产生登录,但可能还有更多不会产生登录,并且会显示为空白或带有管道输出。其中一些可能有来自 init 的输出,不要将其与 X 的输出混淆。根据我的经验,X 和孩子们总是发出大量警告和消息(关于缺少字体、贬值的调用等)。
如果您不通过 GUI 登录,那么它将是您启动 X 的任何 VT,这是一个问题,因为除非您退出,否则您不会看到它。我相信通过 GUI 登录,XDM(图形登录)作为特权进程运行,这意味着它可以通过管道输出到/dev/tty7
.startx 1>&2> /dev/tty7
如果您拥有正确的超级用户权限,您也可以 ( )。
答案3
如果您认为,通常一个程序通过执行一系列操作来启动另一个程序man 2 fork
,man 2 execve
然后在该过程中默认文件描述符保持打开状态。
所以答案是,通常输出/错误会发生在父进程输出/错误在 fork 时间指向的位置(当然,除非父程序进行一些重定向)。我认为除非我们确切地知道父程序的名称,否则您不能声明任何更具体的内容。窗口管理器进程很少参与直接启动其他程序。
以我为例
- 按 Ctrl+P(由
xmonad
窗口管理器处理)将启动dmenu_run
dmenu_run
将处理我的输入并启动一些应用程序(例如xkill
)
输出将转到/dev/tty1
因为
xkill
开始于dmenu_run
dmenu_run
开始于xmonad
xmonad
开始于X
X
开始于startx
startx
由我从第一个虚拟控制台手动启动/dev/tty1
仅供参考,如果您想查找输出/错误的去向,或者更好地说为特定进程(具有已知 PID)打开的文件描述符是什么,请执行以下操作:
$ lsof -p PID