Así que estoy tratando de averiguar si stderr
un proceso ha sido redirigido a algún lugar inusual (es un proceso de Java y quiero un volcado de subprocesos, pero se inicia a través de un conjunto de scripts de inicio).
Encuentro mi proceso con pgrep
y lo uso pfiles
para ver qué hay allí:
4366: /foo/bar/plataforma/solaris2/jre_1.5.0/bin/java -Xmx2048m -Xms10 Límite actual: 65536 descriptores de archivos 0: modo S_IFCHR: 0666 dev: 302,0 ino: 6815752 uid: 0 gid: 3 rdev: 13,2 O_RDONLY|O_LARGEFILE /dispositivos/pseudo/mm@0:nulo 1: modo S_IFREG: 0640 dev: 85,56 ino: 26471 uid: 0 gid: 0 tamaño: 10485812 O_WRONLY|O_LARGEFILE 2: modo S_IFREG: 0640 dev: 85,56 ino: 26471 uid: 0 gid: 0 tamaño: 10485812 O_WRONLY|O_LARGEFILE 3: modo S_IFCHR: 0666 dev: 302,0 ino: 6815772 uid: 0 gid: 3 rdev: 13,12
Entonces puedo ver que stdout
y stderr
(descriptores de archivo 1 y 2) apuntan al mismo lugar; Creo que son redirigidos al mismo archivo en los scripts de inicio, por lo que esto concuerda.
Pero cuando busco un archivo con el número de inodo 26471, veo esto:
# encontrar / -inum 26471 /usr/share/man/man3mlib/mlib_MatrixScale_S16_U8_Sat.3mlib /proc/4366/fd/1 /proc/4366/fd/2 /proc/4366/fd/83
El primer resultado es (estoy seguro) un archivo en un sistema de archivos diferente. Las tres entradas /proc
son fds que mi proceso tiene abiertas.
Mirando hacia adentro /proc/4366
, no puedo ver más información de la que obtengo pfiles
.
# ls-li 0 1 2 3 6815752 c--------- 1 sistema raíz 13, 2 20 de enero 14:10 0 26471 --w------- 0 raíz raíz 10485812 20 de enero 13:42 1 26471 --w------- 0 raíz raíz 10485812 20 de enero 13:42 2 6815772 c--------- 1 sistema raíz 13, 12 7 de junio de 2009 3 # archivo 0 1 2 3 0: carácter especial (13/2) 1: texto ascii 2: texto ascii 3: personaje especial (13/12)
(Puedo seguir uno de estos fds y determinar de qué archivo proviene. Lo pregunto porque claramente no entiendo la relación entre los fds y los inodos con suficiente profundidad).
Entonces mi proceso es escribir aalgo(en algunos dispositivos, con el inodo 26471) y los datos luego ingresan en un archivo con un número de inodo diferente. ¿Alguien puede darme una idea de qué podría ser este algo (o incluso decirme si mi razonamiento hasta ahora está totalmente roto)?
Respuesta1
AFAIK, find
busca en los directorios del sistema de archivos. Si ese archivo se eliminó pero aún existe porque está abierto (un truco común en Unix), find
.
No lo he probado en Solaris, peroaquíHay una nota sobre el uso lsof
para identificar dichos archivos "eliminados pero abiertos" y su recuperación a través de uncat /proc/<procid>/fd/<fdid> > /tmp/xxxx
Editar:
Parece que ya has identificado que este es el caso, pero aún te preguntas cómo es posible. Aquí hay una breve explicación:
en el sistema de archivos POSIX, los archivos son manejados por su inode
, y los directorios son poco más que una asignación de "ruta => inodo". Puede tener más de una ruta 'apuntando' al mismo inodo (se llama enlace físico), y el inodo mantiene un recuento de cuántos enlaces tiene. El rm
comando simplemente llama unlink()
a esta ruta, lo que reduce el número de enlaces y "posiblemente" elimina el archivo en sí.
Pero una ruta en el árbol de directorios no es la única referencia posible a un inodo, la apertura fd
de un proceso en ejecución también cuenta, y un archivo 'eliminado' no se eliminará realmente hasta que llegue a 0.
Como mencioné anteriormente, es un truco común: si tiene un archivo temporal que no desea conservar después de que el proceso termine de ejecutarse, simplemente ábralo y "bórrelo" inmediatamente. El identificador abierto funcionará de manera confiable y, cuando finalice el proceso (ya sea normalmente, finalizado o fallando), el sistema eliminará el identificador y eliminará limpiamente el archivo temporal.
Un archivo de registro no es un candidato probable para un archivo de "eliminación automática oculta"; pero no es difícil hacerlo accidentalmente.
Dado que su archivo de registro eliminado todavía está activo y recopilando datos, parece que simplemente copiar el contenido no ayudaría mucho. así que intente crear un nuevo vínculo físico al archivo /proc//fd/, algo así como ln /proc/4366/fd/1 /tmp/xxxx
. Tenga en cuenta que no hay ninguna -s
bandera, por lo que ln
debe crear un nuevo vínculo físico con el mismo inodo que el original, no un vínculo simbólico (que es poco más que un puntero a una ruta existente, y no lo que desea).
Editar:
El ln /proc/... /tmp/...
comando no puede funcionar porque /proc y /tmp están en sistemas de archivos diferentes. Desafortunadamente, no conozco ninguna forma de crear una ruta para un inodo existente. Uno querría que la link()
llamada al sistema tomara un número de inodo y una ruta, pero toma rutas de origen y destino.