Linux

Как предотвратить случайное использование rm -rf ?

Я случайно выполнил rm -rf /*, но я имел в виду rm -rf ./* (обратите внимание на звездочку после косой черты).

alias rm='rm -i' и --preserve-root по умолчанию не помогло мне, так что есть ли какие-нибудь автоматические средства защиты на этот случай?

Я не имел root доступ и сразу отменил команду, но где-то были пропущены разрешения или что-то в этом роде, потому что я заметил, что мой Bash prompt уже «сломался». Я не хочу полагаться на разрешения и не иметь root доступа (я могу совершить ту же ошибку с sudo), и я не хочу идентифицировать загадочные ошибки из-за одного отсутствующего файла где-то в системе, поэтому резервные копии и sudo это хорошо, но я бы хотел чего-то лучшего для данного конкретного случая.

Я использую это для решения сложной задачи программирования, включающей 10 разных вещей. Я погружаюсь в эту задачу достаточно глубоко, у меня не остается времени на проверку флагов и путей, я даже не думаю в терминах команд и аргументов, я думаю в терминах действий типа «empty current dir», другая часть моего времени уходит на перевод их в команды и иногда возникают ошибки. Я хочу, чтобы компьютер исправлял их автоматически.

Ответ 1

Ваша проблема:

Я только что случайно выполнил rm -rf /*, но я имел в виду rm -rf ./* (обратите внимание на звездочку после косой черты).

Решение: Не делайте этого! Практически не используйте ./ в начале пути. Косая черта не добавляет команде никакой ценности и только вносит путаницу.

./* означает то же самое, что и *, поэтому приведенную выше команду лучше записать так:

rm -rf *

 Вот смежная проблема. Я часто встречаю следующее выражение, когда кто-то предположил, что FOO установлен на что-то вроде /home/puppies. Я нашел это в документации одного из крупных производителей программного обеспечения:

rm -rf $FOO/

Но если FOO не установлен, это будет равносильно rm -rf /, что приведет к попытке удалить все файлы в системе. Косая черта здесь лишняя, поэтому в качестве практики не используйте ее. Следующая команда сделает то же самое, но с меньшей вероятностью повреждения вашей системы:

rm -rf $FOO

Я усвоил эти советы трудным путем. Когда несколько лет назад у меня была первая учетная запись суперпользователя, я случайно выполнил rm -rf $FOO/ из сценария оболочки и разрушил систему. Четыре других сисадмина посмотрели на это и сказали: «Ага. Каждый делает это однажды. Вот тебе установочный носитель. Иди и исправь это».

Также я рекомендую такие решения, как --preserve-root и safe-rm. Однако эти решения существуют не для всех Un*x-вариаций и могут не работать на Solaris, FreeBSD и MacOSX. Кроме того, safe-rm требует установки дополнительных пакетов на каждую используемую вами систему Linux. Если вы полагаетесь на safe-rm, что произойдет, когда вы начнете новую работу, а у них не будет установлен safe-rm? Эти инструменты кастомны, и гораздо лучше полагаться на известные настройки по умолчанию и улучшать свои рабочие привычки.

Ответ 2

Лучшие решения связаны с изменением привычки не использовать rm напрямую.

Один из подходов заключается в том, чтобы сначала выполнить команду echo rm -rf /stuff/with/wildcards*. Убедитесь, что вывод непечатных символов выглядит правильно, затем используйте историю оболочки, чтобы выполнить предыдущую команду без echo.

Другой подход заключается в том, чтобы ограничить использование команды echo случаями, когда совершенно очевидно, что именно вы будете удалять. Вместо того чтобы удалять все файлы в каталоге, удалите каталог и создайте новый. Хороший метод переименовать существующий каталог в DELETE-foo, затем создать новый каталог foo с соответствующими разрешениями и, наконец, удалить DELETE-foo. Побочным преимуществом этого метода является то, что команда, занесенная в вашу историю, будет rm -rf DELETE-foo.

cd ..

mv somedir DELETE-somedir

mkdir somedir                      # или rsync -dgop DELETE-somedir somedir для сохранения разрешений

ls DELETE-somedir             # просто чтобы убедиться, что мы удаляем то, что нужно.

rm -rf DELETE-somedir

Если вы действительно настаиваете на удалении многих файлов, потому что вам нужно, чтобы каталог остался (потому что он должен существовать всегда или потому что у вас нет разрешения на его воссоздание), переместите файлы в другой каталог и потом удалите исходный каталог.

mkdir ../DELETE_ME

mv * ../DELETE_ME

ls ../DELETE_ME

rm -rf ../DELETE_ME

Удаление каталога изнутри было бы привлекательным, потому что команда «rm –rf» короткая, а значит, риск опечаток невелик. К сожалению, типичные системы не позволяют этого сделать. Вместо этого вы можете выполнить rm -rf -- "$PWD", с более высоким риском опечаток, но большинство из них не приведут к удалению. Остерегайтесь, так как это оставляет опасную команду в истории оболочки.

Когда есть возможность, используйте контроль версий. Используйте не «rm», а «cvs rm» или что-то подобное, тогда последнюю команду можно будет отменить.

Существует множество других решений, связанных с изменением команды rm. Ограничение этого подхода заключается в том, что однажды вы окажетесь на машине с настоящей командой rm и автоматически вызовете rm, ожидая подтверждения... а в следующий момент вы будете восстанавливать систему из резервных копий.

Ответ 3

Решением этой проблемы является регулярное резервное копирование. Каждый раз, когда вы создаете что-то, что не хотите рисковать потерять, создавайте резервные копии. Если вы считаете, что регулярное резервное копирование слишком утомительно, упростите процесс. Например, если вы работаете с исходным кодом, используйте такой инструмент, как git, для зеркалирования кода и сохранения истории на другой машине. Если вы работаете с документами, создайте скрипт, который выполнит rsyncs ваших документов на другую машину.

Ответ 4

Когда я удаляю каталог рекурсивно, я ставлю -r и -f в конце команды, например, rm /foo/bar -rf. Таким образом, если я случайно нажму Enter слишком рано, еще не набрав весь путь, команда не будет рекурсивной, поэтому она, скорее всего, не причинит вреда. Если я нажму Enter, пытаясь набрать слеш после /foo, я напишу rm /foo, а не rm -rf /foo.

Это хорошо работает на системах, использующих GNU coreutils, но утилиты на некоторых других Unix не позволяют помещать опции в конец таким образом. К счастью, я не часто пользуюсь подобными системами. 

Ответ 5

Избегайте использования globbing. В Bash вы можете установить noglob. Но опять же, когда вы переходите на систему, где noglob не установлен, вы можете забыть об этом и действовать так, как если бы он был установлен. Установите noclobber, чтобы mv и cp тоже не уничтожали файлы.

Используйте браузер файлов для удаления. Некоторые файловые браузеры предлагают использовать корзину (например, Konqueror).

Еще один способ избежать globbing заключается в следующем: в командной строке я набираю echo filenamepattern >> xxx. Затем я редактирую файл с помощью Vim или vi, чтобы проверить, какие файлы должны быть удалены (следите за символами шаблона имени файла в filenmates.), а затем использую %s/^/rm -f/, чтобы превратить каждую строку в команду удаления. Таким образом, вы увидите каждый файл, который будет удален, прежде чем сделать это.

Схожие статьи

Linux

Обеспечение безопасности нового сервера Ubuntu

Linux

Как объединить две статические библиотеки «ar» в одну

Linux

Синхронизация снимков LVM с сервером резервного копирования

Linux

Есть ли альтернатива /dev/urandom?