Мой destkop файл: /usr/share/applications/write-to-stdout-sterr.desktop
[Desktop Entry]
# created by autocreate-desktop-files-for-pycharm.py
Name=write-to-stdout-sterr
Icon=/usr/share/pixmaps/python2.7.xpm
Exec=/var/tmp/write-to-stdout-sterr.py
Terminal=false
Type=Application
Categories=Application
Я запускаю этот скрипт:
#!/usr/bin/python
import sys
import time
import datetime
sys.stdout.write('########### stdout %s\n' % datetime.datetime.now())
sys.stderr.write('+++++++++++ sdterr %s\n' % datetime.datetime.now())
time.sleep(120)
И chmod a+rx /var/tmp/write-to-stdout-sterr.py
Если я называю это через ключ окон (средство запуска)
Я хочу видеть, куда stdout/stderr переходит в.
root@aptguettler:~# ls -l /proc/$(pgrep -f write-to)/fd
Вывод:
insgesamt 0
lr-x------ 1 tguettler tguettler 64 Dez 16 12:42 0 -> /dev/null
lrwx------ 1 tguettler tguettler 64 Dez 16 12:42 1 -> 'socket:[346100]'
lrwx------ 1 tguettler tguettler 64 Dez 16 12:42 2 -> 'socket:[346100]'
Где делает socket:[346100]
перейти в? Как я могу видеть другой конец сокета?
Выше вопроса более точная версия этого вопроса: То, где сообщения об ошибках неудавшегося приложения, запускается?
Сокет является одной конечной точкой ссылки двунаправленной связи. В Вашем случае оба потока вывода пишут в один сокет. Вам нужны два сокета, чтобы иметь "другой конец".
, Куда
socket:[346100]
переходит в?
socket:[346100]
сам сокет. Это - потоки процесса, которые переходят к сокету.
, Как я могу видеть другой конец сокета?
Для наблюдения другой конечной точки, если есть посмотрите rem_address
столбец /proc/net/tcp
наличие inode
346100
.
Основная цель OP — выяснить, как приложения запускаются через файлы Desktop Entries, также известные как .desktop
. На этот вопрос нет ответа, поскольку он зависит от реализации, а спецификации, на которые я ссылался выше, не содержат стандарта относительно того, как стандартные потоки должны быть перенаправлены, если вообще должны быть перенаправлены.
В последних версиях Ubuntu можно найти, где эти сокеты соединяются. Число, которое вы видите в скобках, — это индексный дескриптор виртуальной файловой системы ядра sockfs. Согласно руководству proc(5):
For file descriptors for pipes and sockets, the entries will
be symbolic links whose content is the file type with the
inode. A readlink(2) call on this file returns a string in
the format:
type:[inode]
For example, socket:[2248868] will be a socket and its inode
is 2248868. For sockets, that inode can be used to find more
information in one of the files under /proc/net/.
Однако здесь есть одна загвоздка. В случае каналов индекс для чтения и записи один и тот же. Для пары сокетов - не гарантируется. Однако, скорее всего, это сокет домена Unix, и теоретически мы могли бы найти его файловый дескриптор. Согласно ответу Стефана Шазеласа , я использовал ss -x
на виртуальной машине Ubuntu 18.04 с XFCE, чтобы найти конечную точку сокета с расширением .desktop в вашем вопросе, но немного измененный код:
#!/usr/bin/env python3
import sys
import time
import datetime
while True:
sys.stdout.write('########### stdout %s\n' % datetime.datetime.now())
sys.stderr.write('+++++++++++ sdterr %s\n' % datetime.datetime.now())
time.sleep(1)
Я нашел сокет, и его конечная точка, по-видимому, указывает на сокет systemd:
adminx@bionicbeaver:~$ ls -l /proc/$(pgrep -f write-to-stdout )/fd/{0,1,2}
lr-x------ 1 adminx adminx 64 Dec 23 09:01 /proc/3773/fd/0 -> /dev/null
lrwx------ 1 adminx adminx 64 Dec 23 09:01 /proc/3773/fd/1 -> 'socket:[27437]'
lrwx------ 1 adminx adminx 64 Dec 23 09:01 /proc/3773/fd/2 -> 'socket:[26621]'
adminx@bionicbeaver:~$ ss -x | grep 27437
u_strESTAB 0 0 /run/systemd/journal/stdout 27438 * 27437
Правильно, поэтому с измененным кодом вы увидите в выводе journalctl -f
, что код записывает в системный журнал
Dec 23 09:49:47 bionicbeaver /usr/lib/gdm3/gdm-x-session[1441]: ########### stdout 2019-12-23 09:49:45.726394
Dec 23 09:49:47 bionicbeaver /usr/lib/gdm3/gdm-x-session[1441]: ########### stdout 2019-12-23 09:49:46.734060
Dec 23 09:49:47 bionicbeaver /usr/lib/gdm3/gdm-x-session[1441]: ########### stdout 2019-12-23 09:49:47.734603
Dec 23 09:49:47 bionicbeaver /usr/lib/gdm3/gdm-x-session[1441]: +++++++++++ sdterr 2019-12-23 09:49:45.726459
Dec 23 09:49:47 bionicbeaver /usr/lib/gdm3/gdm-x-session[1441]: +++++++++++ sdterr 2019-12-23 09:49:46.734122
Dec 23 09:49:47 bionicbeaver /usr/lib/gdm3/gdm-x-session[1441]: +++++++++++ sdterr 2019-12-23 09:49:47.734787
Обратите внимание, что за передачу этих сообщений отвечает диспетчер рабочего стола gdm. Если вы немного отфильтруете /proc
, как описано в связанном вопросе о каналах, вы увидите, что несколько процессов подключаются к тому же сокету, что и клиенты, а gdm действует как своего рода сервер для этого.
Однако это непостоянное поведение. Согласно ответам Гилле и Стефана, поиск другого конца пары сокетов возможен только с ядром версии выше 3.3, и, как я уже упоминал ранее, это зависит от реализации среды рабочего стола/оконных менеджеров. как связать стандартные потоки. В другом дистрибутиве на основе Debian с Mutter тот же код отображается только в /dev/null
$ ls -l /proc/$(pgrep -f /var/tmp/write-to-stdout-sterr.py)/fd/{0,1,2}
lr-x------ 1 xie xie 64 Dec 23 16:38 /proc/16975/fd/0 -> /dev/null
l-wx------ 1 xie xie 64 Dec 23 16:38 /proc/16975/fd/1 -> /dev/null
l-wx------ 1 xie xie 64 Dec 23 16:38 /proc/16975/fd/2 -> /dev/null
В заключение, не ожидайте, что это вообще будет переносимым. Будьте явными, если вы хотите получить stdout или stderr приложений, запущенных через записи рабочего стола.