所以我试图找出一个进程的stderr
是否被redirect到一些不寻常的(这是一个Java进程,我想要一个线程转储,但它是通过一个启动脚本巢启动)。
我使用pgrep
查找我的进程,并使用pfiles
来查看结果:
4366:/foo/bar/platform/solaris2/jre_1.5.0/bin/java -Xmx2048m -Xms10 当前rlimit:65536个文件描述符 0:S_IFCHR模式:0666 dev:302,0 ino:6815752 uid:0 gid:3 rdev:13,2 O_RDONLY | O_LARGEFILE /装置/伪/毫米@ 0:空 1:S_IFREG模式:0640 dev:85,56 ino:26471 uid:0 gid:0大小:10485812 O_WRONLY | O_LARGEFILE 2:S_IFREG模式:0640 dev:85,56 ino:26471 uid:0 gid:0大小:10485812 O_WRONLY | O_LARGEFILE 3:S_IFCHR模式:0666 dev:302,0 ino:6815772 uid:0 gid:3 rdev:13,12
所以我可以看到stdout
和stderr
(文件描述符1和2)指向相同的地方; 我认为他们被redirect到启动脚本中的同一个文件,所以这个logging。
但是当我查找一个inode号码为26471的文件时,我看到:
#find / -inum 26471 /usr/share/man/man3mlib/mlib_MatrixScale_S16_U8_Sat.3mlib 的/ proc / 4366 / FD / 1 的/ proc / 4366 / FD / 2 的/ proc / 4366 / FD / 83
第一个命中是(我确定)在不同的文件系统上的文件。 /proc
中的三个条目是fds,我的进程已经打开。
在/proc/4366
,我看不到比pfiles
更多的信息。
#ls -li 0 1 2 3 6815752 c --------- 1根系统13,2月20日14:10 0 26471 - w ------- 0 root root 10485812 Jan 20 13:42 1 26471 - w ------- 0 root root 10485812 Jan 20 13:42 2 6815772 c --------- 1根系sys 13,2009年6月12日3 #文件0 1 2 3 0:特殊字符(13/2) 1:ascii文本 2:ascii文本 3:字符特殊(13/12)
(我可以找出这些文件中的一个,并找出它是哪个文件,因为我明显不明白fds和inode之间的关系是否足够深入)。
所以我的过程正在写入某些东西 (在某些设备上,使用inode 26471),然后数据将进入具有不同inode编号的文件。 任何人都可以给我一个这东西可能是什么的想法(或者甚至让我知道,如果我的推理到目前为止是完全破碎)?
AFAIK, find
search文件系统的目录。 如果该文件被删除,但仍然存在,因为它是开放的(一个普通的技巧在Unix上),它不会被find
。
我还没有尝试在Solaris中,但是这里有一个关于使用lsof
来标识这样的'已删除但是打开'的文件,并通过cat /proc/<procid>/fd/<fdid> > /tmp/xxxx
编辑 :
似乎你已经确定了这种情况,但仍然想知道如何可能。 这里是一个简短的解释:
在POSIX文件系统上,文件由它的inode
来处理,而这些目录只是一个“path => inode”映射。 你可以有多个path指向同一个inode(它被称为硬链接),inode保持它有多less链接的计数。 rm
命令简单地在这个path上调用unlink()
,这会减less链接数量,并且可能会删除文件本身。
但是目录树上的path并不是对inode的唯一可能的引用,正在运行的进程上的开放fd
也会计数,并且“已删除”文件将不会真正删除,直到它变为0。
正如我在上面提到的那样,这是一个常见的伎俩:如果你有一个临时文件,在你的进程结束运行后你不需要保留,只需打开它并立即“删除”它即可。 打开的句柄将可靠地工作,并且当您的过程完成(正常,死亡或崩溃)时,系统将删除句柄并干净地删除临时文件。
日志文件不是这样一个“隐藏自动删除”文件的可能的候选人; 但不小心却不难
由于您删除的日志文件仍然存在,并收集数据,似乎只是简单地复制内容不会有多大帮助。 所以尝试创build一个新的硬链接到/ proc // fd /文件,如ln /proc/4366/fd/1 /tmp/xxxx
。 请注意,没有-s
标志,所以应该创build一个新的硬链接与原始的相同的inode,而不是一个符号链接(这只是一个指向现有path的指针,而不是你想要的)。
编辑 :
ln /proc/... /tmp/...
命令无法工作,因为/ proc和/ tmp位于不同的文件系统中。 不幸的是,我不知道为现有的inode创build一个path名。 人们会希望link()
系统调用会占用一个inode编号和一个path,但是它需要源path和目标path。