Как закрыть файловый дескриптор из другого процесса в системах Unix - PullRequest
26 голосов
/ 27 ноября 2008

Вы можете использовать команду lsof для получения файловых дескрипторов для всех запущенных процессов, но я хотел бы закрыть некоторые из этих дескрипторов, не находясь внутри этого процесса. Это можно сделать в Windows, поэтому вы можете легко разблокировать какое-либо приложение.

Есть ли какая-либо команда или функция для этого?

Ответы [ 5 ]

76 голосов
/ 27 ноября 2008

Я не знаю, почему вы пытаетесь это сделать, но вы должны иметь возможность присоединиться к процессу, используя gdb, а затем вызвать close () на fd. Пример:

В одной оболочке: кошка

В другой оболочке:

$pidof cat
7213

$gdb -p 7213

...
lots of output
...

(gdb)

Теперь вы указываете gdb выполнить close (0):

(gdb) p close(0)

$1 = 0

(gdb) c

Continuing.

Program exited with code 01.
(gdb)

В первой оболочке я получаю такой вывод:

cat: -: Bad file descriptor

cat: closing standard input: Bad file descriptor
3 голосов
/ 27 ноября 2008

Я так не думаю, но lsof дает вам PID процесса, который открыл файл, так что вы можете полностью убить процесс или, по крайней мере, отправить сигнал, чтобы он завершился.

2 голосов
/ 29 ноября 2008

В Unix гораздо меньше необходимости делать это, чем в Windows.

В Windows большинство программ, как правило, "блокируют" (фактически запрещают совместное использование) открываемые ими файлы, поэтому их нельзя прочитать / записать / удалить другой программой.

В Unix большую часть времени этого не происходит. Блокировка файлов в Unix в основном носит рекомендательный характер и блокирует только другие попытки блокировки, а не обычные операции чтения / записи / удаления. Вы даже можете удалить текущий каталог процесса.

О единственной ситуации, которая возникает при обычном использовании в Unix, является попытка размонтировать файловую систему (любая ссылка на смонтированную файловую систему может заблокировать размонтирование).

2 голосов
/ 27 ноября 2008

Я сомневаюсь в этом. Файловые дескрипторы являются локальными для процесса, stdout равен 1 для всех процессов, но они, конечно, все еще ссылаются на уникальные потоки.

Возможно, было бы полезно более подробно рассказать о проблеме блокировки, которую вы пытаетесь решить.

2 голосов
/ 27 ноября 2008

В Windows вы можете использовать программу для этого, потому что кто-то написал программу, которая вставляет драйвер устройства в работающее ядро, чтобы сделать это. Между прочим, это может быть опасно, потому что после закрытия дескриптора, который использовало сломанное приложение, приложение не знает, что дескриптор был закрыт, и когда приложение открывает какой-либо другой не связанный объект, оно не знает что тот же дескриптор теперь может ссылаться на какой-то другой не связанный объект. Вы действительно хотите убить сломанное приложение как можно скорее.

В Linux вы можете использовать такую ​​же технику. Напишите программу, которая вставит модуль в работающее ядро. Свяжитесь с модулем и скажите ему, какие ручки закрывать. Это будет одинаково опасно.

...