我的桌面文件:/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
如果我通过 Windows 键(启动器)调用它
我想看看 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]
?我怎样才能看到套接字的另一端?
上述问题是该问题的更精确版本:应用程序启动失败的错误消息在哪里?
答案1
套接字是双向通信链路的一个端点。就您而言,两个输出流都写入一个套接字。您需要两个套接字才能拥有“另一端”。
socket:[346100]
去哪儿?
socket:[346100]
是套接字本身。它是进入套接字的进程流。
我怎样才能看到插座的另一端?
要查看另一个端点(如果存在),请查看具有 的rem_address
列。/proc/net/tcp
inode
346100
答案2
OP 的主要目标是找出应用程序是如何通过桌面条目又名.desktop
文件。这个问题没有答案,因为它依赖于实现,而我上面链接的规范没有提供关于如何标准流如果需要的话,应该被重定向。
对于较新的 Ubuntu 版本,可以找到这些套接字连接的位置。括号中的数字是内核中的 inodesockfs虚拟文件系统. 每进程(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/.
但是,这有一个问题。对于管道,读取和写入端的 inode 是相同的。对于套接字对 - 不能保证。但是,这很可能是一个 Unix 域套接字,理论上我们可以找到它的文件句柄。每Stephane Chazelas 的回答,我已经在带有 XFCE 的 Ubuntu 18.04 虚拟机上使用ss -x
你问题中的 .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 才有可能找到套接字对的另一端,正如我之前提到的,如何连接标准流取决于桌面环境/窗口管理器实现。在具有 Mutter 的另一个基于 Debian 的发行版上,相同的代码仅映射到/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,请明确说明。