Поскольку find
получил синтаксис -exec... +
, нет особого смысла использовать xargs
, но как вы просите об этом:
find /main_directory -not -perm 0755 | xargs chmod 755
Ядро не проверяет права доступа к описаниям файлов. Их можно даже продублировать для других процессов, у которых никогда не было доступа к исходному файлу, путем передачи fd .
Единственное, что, я думаю, вы могли бы попробовать, это вручную найти процессы с открытыми файловыми дескрипторами и использовать подлый трюк, чтобы закрыть их 1 . Есть пример такого «хитрого трюка» — подключить отладчик(gdb
)и использовать его для закрытия файла fd.
Это очень экстремальный поступок. Невозможно узнать, как поведет себя процесс, если его FD внезапно закроется. В некоторых случаях у процессов может быть файл, сопоставленный с памятью, поэтому, если вам удастся закрыть файл и удалить любое сопоставление памяти, процессы не ожидают, что это приведет к сбою из-за ошибки сегментации.
Гораздо лучше определить, какие процессы используют файл, и вручную убить их. По крайней мере, таким образом вы можете попросить их корректно завершить работу и не повредить другие данные.
1как упоминалось в комментариях, лучшим способом выполнения этой работы будет вызов dup2
, а не close
, чтобы изменить fd так, чтобы он указывал на /dev/null
вместо исходного файла. Это связано с тем, что код не ожидает, что он закроется, и может делать некоторые очень странные и небезопасные вещи, когда число fd ()перерабатывается.
Вы не можете аннулировать существующие файловые дескрипторы, кроме как с помощью «хитрых уловок», подобных упомянутым Филипом Коулингом. Однако вы можете добиться аналогичного эффекта (достаточно )портативным способом.
Допустим, вы хотите запретить процессам, у которых уже открыто foo
, продолжать запись в foo
. Что вы можете сделать, так это:cp foo foo2; chmod -w foo2; mv foo2 foo
. Теперь любые процессы, у которых был открыт старый foo
, будут продолжать запись в этот файл, который больше не известен как foo
(, имеет на одну жесткую ссылку меньше, чем раньше ). Ни один из этих процессов не может повлиять на новый foo
, так как они не могут открыть его для записи.
Если вы хотите запретить чтение, аналогичная стратегия cp foo foo2; chmod -r foo2; truncate foo; mv foo2 foo
. Здесь старый foo
усекается на -месте (, т. е. уменьшается до нуля без удаления ), так что процессы, у которых было открыто foo
, не увидят содержимого при следующей попытке читать из него, и они не могут открыть новый foo
. Однако это не гарантирует работу, так как если какие-либо процессы имели mmap
ed foo
, то не указано, действительно ли усечение влияет на эти сопоставления.
Это очень -интересный вопрос, и изучение его на самом деле доставило больше удовольствия в воскресенье, чем просмотр Netflix:-)
Значит:
В зависимости от вашего варианта использования я вижу другие возможности: