2008-11-27 9 views
26

Puede usar el comando lsof para obtener descriptores de archivos para todos los procesos en ejecución, pero lo que me gustaría hacer es cerrar algunos de esos descriptores sin estar dentro de ese proceso . Esto se puede hacer en Windows, por lo que puedes desbloquear fácilmente alguna aplicación.Cómo cerrar un descriptor de archivo de otro proceso en sistemas Unix

¿Hay algún comando o función para eso?

Respuesta

2

En Windows puede usar un programa para hacerlo porque alguien escribió un programa que inserta un controlador de dispositivo en el kernel en ejecución para hacerlo. Por cierto, puede ser peligroso hacerlo, porque después de cerrar un identificador que estaba usando una aplicación dañada, la aplicación no sabe que el identificador estaba cerrado, y cuando la aplicación abre algún otro objeto no relacionado, no lo sabe. que el mismo mango ahora podría referirse a algún otro objeto no relacionado. Realmente desea matar la aplicación rota lo antes posible.

En Linux seguramente puede usar el mismo tipo de técnica. Escriba un programa que inserte un módulo en el kernel en ejecución. Comuníquese con el módulo y dígale qué maneja para cerrar. Será igualmente peligroso hacerlo.

1

Lo dudo. Los descriptores de archivo son process-local, stdout es 1 para todos los procesos, sin embargo, todavía hacen referencia a flujos únicos, por supuesto.

Quizás más detalles sean útiles sobre el problema de bloqueo que estás tratando de resolver.

3

No lo creo, pero lsof le proporciona el PID del proceso que ha abierto el archivo, por lo que lo que puede hacer es matar completamente el proceso o al menos enviar una señal para que pueda salir.

+0

Tengo init (pid 1) con un directorio abierto en un hd externo de alguna manera. No puedo matar a init, y quiero desmontar limpiamente la unidad antes de apagarla. – fuzzyTew

72

No sé por qué estás tratando de hacer esto, pero deberías poder adjuntar al proceso usando gdb y luego llamar a close() en el fd. Ejemplo:

En una cáscara: Gato

En otra línea de comandos:

$pidof cat 
7213 

$gdb -p 7213 

... 
lots of output 
... 

(gdb) 

Ahora te dice GDB para ejecutar estrecha (0):

(gdb) p close(0) 

$1 = 0 

(gdb) c 

Continuing. 

Program exited with code 01. 
(gdb) 

En la primera cáscara de recibo esta salida:

cat: -: Bad file descriptor 

cat: closing standard input: Bad file descriptor 
+2

Mejor tarde que nunca, pero este consejo funciona perfectamente cuando Eclipse decide quedarse sin fd en los momentos más mal sincronizados.Saludos :) – Benjamin

+0

Formato feo pero excelente ejemplo –

+1

@Seb, creo que esta debería ser la respuesta aceptada, en realidad da una respuesta a la pregunta. – Yonatan

2

Hay mucha menos necesidad de hacer esto en Unix que en Windows.

En Windows, la mayoría de los programas tienden a "bloquear" (de hecho, a negar el intercambio) los archivos que abren, por lo que no pueden ser leídos/escritos/eliminados por otro programa.

En Unix, la mayoría de las veces esto no sucede. El bloqueo de archivos en Unix es principalmente de asesoramiento, y solo bloqueará otros intentos de bloqueo, no las operaciones normales de lectura/escritura/eliminación. Incluso puede eliminar el directorio actual de un proceso.

Acerca de la única situación que aparece en el uso normal en Unix es cuando se trata de desmontar un sistema de archivos (cualquier referencia en absoluto al sistema de archivos montado puede bloquear el desmontaje).

Cuestiones relacionadas