Я хочу "перечислить" все файлы, которые НЕ открыты, в определенном каталоге с помощью команды поиска GNU. Теперь я могу перечислить открытые файлы, но не могу придумать, как сделать это наоборот.
find /my/dir/* -exec lsof {} \;
Есть идеи, как это можно сделать?
find /my/dir -type f | while read filename ; do fuser -s $filename || echo $filename ; done
Это использует find только для создания списка файлов. Затем цикл while перебирает список результатов для каждого результата, который он запускает. fuser -s $filename
который завершится успешно, если что-то использует файл.
В || echo $filename
часть означает «если сбой фьюзера (то есть никто не использует файл), укажите имя файла»
Вот что я использую
$ find . ! -exec sudo fuser -s "{}" 2>/dev/null \; -exec echo {} \;
Он использует две изящные особенности find
:
exec
s связаны вместе, аналогично операции bash &&
. Если первый exec возвращает ненулевой код выхода, то второй exec не вызывается. !
является обратной операцией для кода выхода. fuser
возвращает 1 для файла, к которому нет доступа, и 0 для файла, к которому был осуществлен доступ, поэтому нам нужно перевернуть его, чтобы получить то, что вы хотите. Обратите внимание, что я добавил sudo
в фьюзер, чтобы он мог находить файлы, открытые другими пользователями. Без этого он с радостью сообщит, что файл не открыт, в то время как на самом деле он просто сообщает, что файл не открыт процессом, на мониторинг которого у вас есть разрешение
Также стоит упомянуть - очевидно, что вызов fuser дороже, чем просто проверка информации inode, поэтому, если у вас есть другие фильтры, которые вас интересуют в дополнение к «это открытый файл», вы должны сначала применить эти фильтры к поиску, прежде чем делать более дорогая проверка термоэлемента