У меня есть несколько задач cron, каждая из которых оставляет отдельный файл журнала. Успешные задачи не производят никаких результатов, поэтому я получаю много пустых журналов.
Я бы хотел очищать его автоматически каждый день. Запрос find
искать size = 0 легко, однако я хотел бы быть уверен, что я не удаляю журнал, который был только что создан запущенной задачей, но еще не закрыт.
Есть ли способ сказать find
чтобы пропустить открытые файлы, или мне нужно прибегнуть к lsof
?
Насколько мне известно, простого способа сделать это с помощью find нет.
Решение первое
Создать список открытых файлов в целевой папке lsof.lst
. и сгенерируйте список поиска этой папки. затем отобразить файлы в find.lst
что не в lsof.lst
список.
для создания lsof.lst используйте следующую команду:
lsof +D folderName | awk '{ if(NR>1)print $9 }' | sort | uniq > lsof.lst
а затем следующую команду, чтобы показать файлы, которые в настоящее время не открыты в той же папке:
find folderName | grep -v -f lsof.ls
Решение второе
Вы также можете сделать это за один раз вот так:
find folderName | grep -v -E `lsof +D folderName | awk '{ if(NR>1)print $9 }' | sort | uniq | awk '{print $0}' ORS='|' | sed 's/.$//'`
Объяснение
Теперь я попытаюсь объяснить команду, чтобы вы могли улучшить ее, изменить или использовать несколько инструментов командной строки в будущем.
find folderName
создаст список всех файлов в этой папке и подпапках. вывод команды find передается по конвейеру grep
который здесь используется с -v
переключатель, чтобы исключить элементы, указанные в -E
параметры из конвейерного вывода команды find. Результатом будет вывод find
минус элементы, указанные в -E
параметр.
Хитрость здесь в том, чтобы сгенерировать список открытых файлов и поместить его в формат, который grep -v -E
ожидает и может работать с. grep -E принимает список строк, разделенных знаком "|".
lsof +D FolderName
сгенерирует список открытых файлов в этой папке, но список включает заголовок и множество столбцов, один из которых является именем файла, и он может содержать дубликаты. Итак, мы используем awk '{ if(NR>1)print $9 }'
чтобы сделать две вещи, удалите первую строку с помощью if(NR>1)
и распечатайте только столбец, содержащий имя файла с print $9
. Результатом является список имен файлов открытых файлов в этой папке без заголовка.
Чтобы удалить дубликаты, вывод передается на sort
а потом uniq
, а следующая команда awk '{print $0}' ORS='|'
превращает список в предложение, разделенное символом "|", а последняя команда удаляет последний символ "|" поскольку это чрезмерно.
заключая эту команду в обратные кавычки '' executes that command in that spot and feeds the output to the
grep -v -E` команда.