Я написал скрипт, который удаляет все, кроме двух последних файлов в папке:
#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder \
| head -n -2 \
| xargs printf -- "'/path/to/some/folder/%s'\n" \
| xargs sudo rm -rf
Этот скрипт будет выполняться как задание cron каждый день.
Аргументация следующая:
Получить список всех используемых файлов
ls -1
(так что я получаю один файл на строку);Удалите последние два из списка, используя
head -n -2
;Поскольку
ls
печатает относительные пути, используйте этуxargs printf
вещь, чтобы добавить путь к папке и сделать ее абсолютным путем;Отправь их в
sudo rm -rf
пользованиеxargs
.
Каждый имеет доступ к этой папке, поэтому любой может создавать и удалять любые файлы в этой папке.
Проблема в том, что sudo rm -rf
это страшно. xargs sudo rm -rf
невероятно страшно
Я хочу быть уверен, что никто не сможет повредить другие папки / системы, создав умные файлы для удаления (случайно или намеренно). Я не знаю, что-то умное, как:
file with / spaces.txt
что может привести к супер страшно sudo rm -rf /
.
РЕДАКТИРОВАТЬ: Моя ошибка, имена файлов не могут содержать /
, так что эта конкретная проблема не возникнет, но вопрос о том, есть ли другие риски все еще остается.
Вот почему я использую --quoting-style=shell-always
, это должно предотвратить любые уловки с файлами с пробелами. Но теперь я задаюсь вопросом, может ли кто-нибудь быть более умным с пробелами и кавычками в имени файла, возможно.
Мой сценарий безопасен?
Примечание: мне нужно, sudo
потому что я обращаюсь к папке удаленно (с подключенного сетевого диска с помощью mount
), и я не могу заставить его работать без sudo.
printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?/
в имени? Я пытаюсь добиться этого здесьls
вывод, это уже плохо написанная команда, даже с кавычками.ls
я также думаю, что он также использует локаль для порядка сортировки, поэтому я не понимаю, какова цельhead
удаления последних 2 (если только вы не пытаетесь избавиться.
и от того,..
что iirc не разрешено использовать в качестве аргументов вrm
любом случае. Просто используйтеfind /path/to/folder -type f delete
. И нет,sudo
если вы запускаете из cron - cron уже на корневом уровнеОтветы:
В Linux любой символ является допустимым символом имени файла, кроме:
\0
(ASCII NUL): используется для завершения строки в C/
(косая черта): используется для разделения путиИтак, ваш подход определенно не будет работать во многих случаях, как вы можете себе представить, например, обрабатывает ли он символ новой строки (
\n
) в имени файла? ( Подсказка: нет ).Несколько заметок:
ls
; использовать специальные инструменты (для большинства случаев есть хотя бы один)xargs
, посмотрите, сможете ли вы сойти с рукfind ... -exec
; в большинстве случаев вам будет хорошо только сfind
однимЯ думаю, что это поможет вам сейчас. Steeldriver уже предоставил идею NUL в комментариях (
printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
), используйте это как отправную точку.источник
find
, спасибо за предложение.ls
подход к синтаксическому анализу потерпит неудачу, например, учли ли вы новую строку в имени файла?head -z
делать? Звучит смешно, но у меня нетman
ниinfo
в моем контейнере CoreOS Linux ... Не могу найти в Интернете. Я получаюhead: invalid option 'z'
head
(поставляется с GNUcoreutils
). Вот онлайн-версия: manpages.ubuntu.com/manpages/xenial/man1/head.1.htmlxargs
поддерживает некоторые кавычки: с одинарными кавычками, двойными кавычками или обратной косой чертой, что позволяет ему принимать произвольные аргументы¹, но с синтаксисом, который отличается от синтаксиса кавычек, подобного оболочкам типа Борна.Реализация GNU,
ls
как в Ubuntu, не имеет режима цитирования, совместимого сxargs
форматом ввода.Его
ls --quoting-style=shell-always
совместим с ksh93, Баш и ЗШ оболочек со ссылкой синтаксис, но только тогда , когда выходной сигналls
интерпретируется оболочки в той же местности , какls
было , когда это выход его. Кроме того, следует избегать использования некоторых локалей, таких как BIG5, BIG5-HKSCS, GBK или GB18030.Таким образом, с этими оболочками вы можете сделать:
Но это имеет небольшое преимущество перед:
Единственный случай, когда это становится полезным, это когда вы хотите использовать
-t
опциюls
сортировки файлов по mtime / atime / ctime или-S
/-V
. Но даже тогда вы можете использоватьzsh
s:например, для сортировки файлов по mtime (используйте
oL
для-S
иn
для-V
).Чтобы удалить все, кроме двух самых последних измененных обычных файлов:
Still все еще существуют некоторые ограничения по длине (
execve()
и в некоторых реализациях не-GNUxargs
намного меньше произвольных), и некоторые реализации не-GNUxargs
будут задыхаться от ввода, который содержит последовательности байтов, не образующих допустимых символов.источник