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/, чтобы превратить каждую строку в команду удаления. Таким образом, вы увидите каждый файл, который будет удален, прежде чем сделать это.

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

Как установить Gnome 3, что такое графическая оболочка Gnome Shell
Linux

Как установить Gnome 3, что такое графическая оболочка Gnome Shell

Linux

Безопасный стандартный набор правил iptables для базового веб-сервера HTTP(s)

Linux

Стоит ли блокировать ICMP?

Linux

Существуют ли стандартные коды состояния выхода в Linux