Куда идет вывод из приложения, запущенного из оконного менеджера?

10

Если вы запускаете приложение из терминала, вы можете видеть вывод в stdout и stderr, но если приложение запускается из оконного менеджера, куда обычно выводятся эти файлы? В / dev / null?

Август Карлстрем
источник
1
Предложение: используйте, ps fauxчтобы проверить, какой tty / pts связан с процессом. если нет или "?" это вероятно теряется в пустоте. (это просто идея, я могу ошибаться)
mveroone
@Kwaio: значение - знак вопроса (?), Поэтому, как вы говорите, оно, вероятно, теряется в пустоте.
Август Карлстром
2
Если вы запустили свою графическую оболочку из gdm или kdm, выходной файл можно найти в~/.xsession-errors
Shadur

Ответы:

8

Вывод приложения, запущенного из оконного менеджера, происходит в том же месте, что и вывод самого оконного менеджера. (Если приложение не перенаправляет его, но типичные приложения с графическим интерфейсом этого не делают.)

Вы можете узнать, куда выводится WM, посмотрев, что он открыл в дескрипторе файла 1 (стандартный вывод) и дескрипторе файла 2 (стандартная ошибка); как правило, оба будут идти к одному и тому же файлу. Узнайте идентификатор процесса вашего оконного менеджера (попробуйте, например, pgrep metacityили pidof metacityесли Metacity является вашим оконным менеджером - если вы не знаете имя процесса для вашего оконного менеджера, посмотрите на корень одного из деревьев процессов, о которых сообщает ps fили pstree). Предположим, что идентификатор вашего оконного менеджера равен 1234, запустите

lsof -p1234

и найдите строки, соответствующие файловым дескрипторам 1 и 2, или

или

ls -l /proc/1234/fd

Вы можете автоматизировать фильтрацию соответствующих файловых дескрипторов:

lsof -p1234 | awk '$4 ~ /^[12][^0-9]/'
ls -l /proc/1234/fd/[12]

(Примечание: все приведенные выше команды предназначены для Linux. pgrepРаспространена среди других модулей и lsofможет быть установлена ​​практически везде; psпараметры и /procсодержимое у разных модулей различны.)

В обычной ситуации, когда вы запускаете команды из оболочки, запущенной в эмуляторе терминала (xterm, konsole, gnome-терминал и т. Д., Но не при использовании через screen или tmux), вы можете легко проверить, где вывод эмулятора терминала идет, так как эмулятор терминала является родительским процессом вашей оболочки. Это не работает, если эмулятор терминала работает с дополнительными привилегиями, что происходит в некоторых системах, чтобы эмулятор терминала мог записывать в список зарегистрированных пользователей (utmp).

lsof -p$PPID
ls -l /proc/$PPID/fd

Многие дистрибутивы направляют вывод сеанса X на ~/.xsession-errors.

Жиль "ТАК - перестань быть злым"
источник
В моем случае дочерняя родительская иерархия, начинающаяся с WM, - это черный ящик <- lightdm <- lightdm <- init, и все ttys имеют значение «?». Я предполагаю, что вывод не идет никуда.
Август Карлстром
@AugustKarlstrom Тогда pidof blackboxлибо pgrep blackboxполучить PID оконного менеджера, либо напрямую lsof -p$(pidof blackbox). Ttys не имеет ничего общего с этим.
Жиль "ТАК - перестань быть злым"
1
Ах, конечно. Команда ls -l /proc/<blackbox-id>/fdсообщает мне, что stdout идет /dev/nullи stderr идет ~/.xsession-errors.
Август Карлстром
1

Диспетчер окон является дочерним по отношению к X-серверу, поэтому он и его дочерние выходные данные находятся в том же месте, что и X-сервер.

Если вы являетесь единственным пользователем и входите в систему графически, некоторые системы перемещают экземпляр X-сервера с консоли вывода, то есть вы можете переключиться на этот VT и увидеть его. К счастью, обычно это alt-ctrl-f1выходная консоль для экземпляра alt-ctrl-f7X и дисплей X, но вы можете проверить столько, сколько сможете найти. Первые 6 обычно порождают логины, но потенциально есть и другие, которые этого не делают и будут отображаться пустыми или с конвейерным выводом. Для некоторых из них может быть вывод из init, не путайте это с выводом из X. По моему опыту, X и дети всегда выдают значительное количество предупреждений и сообщений (о пропущенных шрифтах, обесцененных вызовах и т. Д.).

Если вы не войдете через GUI, это будет тот VT, с которого вы запустили X, что является проблемой, поскольку вы не увидите этого, пока не выйдете. Я полагаю, что при входе в систему через графический интерфейс XDM (графический вход в систему) запускается как привилегированный процесс, что означает, что он может направлять вывод /dev/tty7. Вы тоже можете ( startx 1>&2> /dev/tty7), если у вас есть права суперпользователя.

лютик золотистый
источник
1
В случае startxили xinitнепосредственно всегда можно настроить ~/.xinitrcперенаправление по мере необходимости, прежде чем делать execна желаемом оконном менеджере. Сам я никогда не пропускал такой вывод. Если мне интересно, что приложение GUI производит, я запускаю его из терминала. Но на самом деле это может быть полезно, поэтому я перенаправил stdout и stderr of ~/.xinitrcна ~/.xinitrc.out.
Мирослав Кошкар
0

Если вы берете это, как правило, одна программа запускает другую, выполняя серии, man 2 forkа man 2 execveзатем в этом процессе по умолчанию файловые дескрипторы остаются открытыми.

Таким образом, ответ заключается в том, что обычно вывод / ошибка происходит там, где вывод / ошибка родительского процесса указывал на время разветвления (если, конечно, родительская программа не выполняет некоторые перенаправления). Я думаю, что вы не можете претендовать на что-то более конкретное, если мы точно не знаем название родительской программы. Процесс оконного менеджера редко участвует в запуске других программ напрямую.

Например в моем случае

  • нажатие 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
Мирослав Кошкар
источник