Назад | Перейти на главную страницу

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

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

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


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


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

Один из приемов, которым я следую, - поставить # в начале при использовании rm команда.

root@localhost:~# #rm -rf /

Это предотвращает случайное выполнение rm в неправильном файле / каталоге. После проверки удалите # с начала. Этот трюк работает, потому что в Bash слово, начинающееся с # заставляет это слово и все оставшиеся символы в этой строке игнорироваться. Так что команда просто игнорируется.

ИЛИ

Если вы хотите предотвратить любой важный каталог, есть еще одна уловка.

Создайте файл с именем -i в этом каталоге. Как можно создать такой странный файл? С помощью touch -- -i или touch ./-i

Теперь попробуй rm -rf *:

sachin@sachin-ThinkPad-T420:~$ touch {1..4}
sachin@sachin-ThinkPad-T420:~$ touch -- -i
sachin@sachin-ThinkPad-T420:~$ ls
1  2  3  4  -i
sachin@sachin-ThinkPad-T420:~$ rm -rf *
rm: remove regular empty file `1'? n
rm: remove regular empty file `2'? 

Здесь * будет расширяться -i в командную строку, поэтому ваша команда в конечном итоге станет rm -rf -i. Таким образом, команда запросит перед удалением. Вы можете поместить этот файл в свой /, /home/, /etc/, и т.д.

ИЛИ

Использовать --preserve-root как вариант rm. в rm включены в более новые coreutils пакеты, этот параметр используется по умолчанию.

--preserve-root
              do not remove `/' (default)

ИЛИ

Использовать сейф-rm

Выдержка с сайта:

Safe-rm - это инструмент безопасности, предназначенный для предотвращения случайного удаления важных файлов путем замены / bin / rm оберткой, которая проверяет заданные аргументы по настраиваемому черному списку файлов и каталогов, которые никогда не должны удаляться.

Пользователи, которые попытаются удалить один из этих защищенных файлов или каталогов, не смогут это сделать, и вместо этого будет показано предупреждающее сообщение:

$ rm -rf /usr
Skipping /usr

Твоя проблема:

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

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

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

rm -rf *

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

rm -rf $FOO/

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

Следующее будет делать то же самое и с меньшей вероятностью повредит вашу систему:

rm -rf $FOO

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

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

Поскольку это на "Serverfault", я хотел бы сказать следующее:

Если у вас десятки и более серверов с большой командой администраторов / пользователей, кто то собирается rm -rf или chown неправильный каталог.

У вас должен быть план восстановления затронутой службы с наименьшим возможным средним временем восстановления.

Лучшие решения включают изменение ваших привычек, чтобы не использовать 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                 # or rsync -dgop DELETE-somedir somedir to preserve permissions
ls DELETE-somedir             # just to make sure we're deleting the right thing
rm -rf DELETE-somedir

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

mkdir ../DELETE_ME
mv * ../DELETE_ME
ls ../DELETE_ME
rm -rf ../DELETE_ME

(Нажми Alt+. ключ.)

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

По возможности используйте контроль версий. Ты не rm, ты cvs rm или что-то еще, и это невозможно.

Zsh может предложить вам перед запуском rm с аргументом, который перечисляет все файлы в каталоге: rm_star_silent (по умолчанию включено) запросы перед выполнением rm whatever/*, и rm_star_wait (по умолчанию выключено) добавляет 10-секундную задержку, в течение которой вы не можете подтвердить. Это имеет ограниченное использование, если вы намеревались удалить все файлы в каком-либо каталоге, потому что вы уже ожидаете приглашения. Это может помочь предотвратить опечатки вроде rm foo * для rm foo*.

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

Вы всегда можете использовать псевдоним, как вы упомянули:

what_the_hell_am_i_thinking() {
   echo "Stop." >&2
   echo "Seriously." >&2
   echo "You almost blew up your computer." >&2
   echo 'WHAT WERE YOU THINKING!?!?!' >&2
   echo "Please provide an excuse for yourself below: " 
   read 
   echo "I'm sorry, that's a pathetic excuse. You're fired."
   sleep 2
   telnet nyancat.dakko.us
}

alias rm -fr /*="what_the_hell_am_i_thinking"

Вы также можете интегрировать его с клиентом twitter из командной строки, чтобы предупредить друзей о том, как вы чуть не унизили себя, протерев жесткий диск с помощью rm -fr /* как корень.

Самый простой способ предотвратить случайное rm -rf /* состоит в том, чтобы избежать любого использования rm команда! На самом деле, у меня всегда было искушение сбежать rm /bin/rm чтобы полностью избавиться от команды! Нет, я не шучу.

Вместо этого используйте -delete вариант find команда, но перед удалением файлов я рекомендую предварительно просмотреть, какие файлы вы удаляете:

find | less

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

find . | less

Убедившись, что это те файлы, которые вы хотите удалить, вы можете добавить -delete вариант:

find path/to/files -delete

Так что не только find безопаснее в использовании, а также выразительнее, поэтому, если вы хотите удалить только определенные файлы в иерархии каталогов, которые соответствуют определенному шаблону, вы можете использовать подобное выражение для предварительного просмотра, а затем удалить файлы:

find path/to/files -name '*~' | less
find path/to/files -name '*~' -delete

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

В этой ветке есть несколько действительно плохих советов, к счастью, большинство из них было отклонено.

Прежде всего, когда вам нужно быть root, станьте root - sudo и различные уловки с псевдонимами сделают вас слабее. И что еще хуже, они сделают вас неосторожным. Научитесь делать все правильно, перестаньте полагаться на псевдонимы, чтобы защитить вас. Однажды вы получите root права на ящик, в котором нет ваших тренировочных колес, и что-нибудь взорвете.

Во-вторых, когда у вас есть root-права, представьте себя водителем автобуса, полного школьников. Иногда вы можете раскачиваться под песню по радио, но в других случаях вам нужно смотреть в обе стороны, притормозить и дважды проверить все свои зеркала.

В-третьих - вы почти никогда действительно должен rm -rf - скорее всего, вы хотите mv something something.bak или mkdir _trash && mv something _trash/

Четвертый - всегда ls ваш подстановочный знак перед rm - Нет ничего сумасшедшего в том, чтобы смотреть на что-то, прежде чем это навсегда разрушить.

Да: не работайте как root и всегда дважды подумайте, прежде чем действовать.

Также посмотрите что-то вроде https://launchpad.net/safe-rm.

Это мой стандарт специально для регулярных выражений в контексте rm, но в этом случае он бы вас спас.

я всегда делаю echo foo*/[0-9]*{bar,baz}* во-первых, чтобы увидеть, чему будет соответствовать регулярное выражение. Получив результат, я возвращаюсь к редактированию в командной строке и меняю echo к rm -rf. я никогда, никогда не использовать rm -rf на непроверенном регулярном выражении.

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

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

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

Одна такая утилита, trash-cli, обсуждается на Unix StackExchange, Вот.

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

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

Одним из важных факторов, позволяющих избежать ошибок такого рода, является отказ от входа в систему с использованием учетной записи root. Когда вы входите в систему с использованием обычного непривилегированного пользователя, вам необходимо использовать sudo для каждой команды. Так что будьте осторожнее.

ZSH спрашивает меня (по умолчанию) перед выполнением rm -rf *.

И ZSH также предоставляет плагин (zsh-safe-rm) добавить safe-rm функциональность, так что rm поместит файлы в корзину вашей ОС вместо того, чтобы навсегда их удалить.

Мне нравится подход Windows к корзине.

Обычно я создаю каталог с именем "/ tmp / recyclebin" для всего, что мне нужно удалить:

mkdir /tmp/recyclebin

И никогда не используйте rm -rf, я всегда использую:

mv target_folder /tmp/recyclebin

Позже я очищаю корзину с помощью скрипта или вручную.

Избегать использования шарик. В Bash вы можете установить noglob. Но опять же, когда вы переходите к системе, где noglob не установлен, вы можете забыть об этом и продолжить работу, как если бы он был установлен.

Устанавливать noclobber предотвращать mv и cp от разрушения файлов тоже.

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

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

Переместите файлы в каталог «чердак» или в архив. Или используйте контроль версий (как было сказано до меня).

Мой процесс удаления на машинах на базе Unix выглядит следующим образом.

  • Тип ls /path/to/intented/file_or_directory в окне терминала, а затем нажмите return (или Tab, по желанию), чтобы просмотреть список файлов.

Если все в порядке,

  • нажмите на up arrow ключ принести ls /path/to/intented/file_or_directory снова из истории терминала.

  • заменить ls с участием rm или rm -r или rm -rf, как требуется. Я лично не люблю использовать -f флаг.

Этот процесс проверки также предотвращает преждевременное выполнение rm команда, что-то, что случилось со мной, прежде чем я начал следовать этому процессу.

Я обычно использую -v флаг, чтобы увидеть, что удаляется, и иметь возможность ^C быстро, если у меня есть малейшие сомнения. Не совсем способ предотвращать плохой rm's, но это может быть полезно для ограничения ущерба в случае, если что-то пойдет не так.

Это может быть сложно, но вы можете настроить роли в SELinux, так что даже если пользователь становится пользователем root через sudo su - (или простой su), возможность удаления файлов может быть ограничена (вы должны входить в систему напрямую как root, чтобы удалить файлы). Если вы используете AppArmor, вы можете что-то сделать аналогичный.

Конечно, другим решением было бы убедиться, что у вас есть резервные копии. :)

Если это поможет кому-то в их собственном случае:

1. Используйте rmsafe:

Он перемещает файлы в "корзину", и у вас всегда есть возможность вернуть их с помощью простого mv:

$ rmsafe /path/to/important/files

Источник: https://github.com/pendashteh/rmsafe

2. Используйте safe:

Вы можете установить псевдоним для rm используя сейф:

$ alias rm="safe rm"

Теперь, если ты бежишь rm /* вы получите это в ответ:

$ rm /*
Are you sure you want to 'rm /bin /boot /data /dev /etc /home /initrd.img /lib /lib64 /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var'? [y/n]

и я верю, что ты не будешь печатать y!

Источник: https://github.com/pendashteh/safe

Я думаю, что это мощный совет по предотвращению с помощью ярлыка расширения * в оболочке:

Сначала введите rm -rf * или rm -rf your/path/*, НЕ вводите Enter ключ. (конечно, вы должны иметь привычку не нажимать быстро / случайно Enter при использовании rm -rf)

Затем нажмите Alt-Shift-8 (т.е. Alt-Shift-*), чтобы явно расширить подстановочный знак "*" в bash. Это также позволит избежать повторного ввода команды «rm -rf *» при навигации по истории.

Наконец, после проверки, что расширение содержит нужные файлы / каталоги, нажмите Enter.

Готово.

К сожалению, я не могу оставить комментарий выше из-за недостаточной кармы, но хотел предупредить других, что safe-rm не панацея от случайных кошмаров массового удаления.

Следующее было протестировано на виртуальной машине Linux Mint 17.1 (предупреждение для тех, кто не знаком с этими командами: НЕ ДЕЛАЙТЕ ЭТО! На самом деле, даже те, кто знаком с этими командами, должны / вероятно никогда не будут делать этого, чтобы избежать катастрофической потери данных):

Текстовая версия (сокращенная):

$ cd /
$ sudo safe-rm -rf *
$ ls
bash: /bin/ls: No such file or directory

Версия образа (полная):

Если сейчас у вас нет настроения приобретать новые привычки, .bashrc/.profile - хорошее место, чтобы добавить несколько тестов, чтобы проверить, не собираетесь ли вы сделать что-нибудь глупое. Я решил, что в функции Bash я могу найти шаблон, который может испортить мне день, и придумал следующее:

alias rm='set -f; myrm' #set -f turns off wildcard expansion need to do it outside of           
                        #the function so that we get the "raw" string.
myrm() {
    ARGV="$*"
    set +f #opposite of set -f
    if echo "$ARGV" | grep -e '-rf /*' \
                           -e 'another scary pattern'
    then
        echo "Do Not Operate Heavy Machinery while under the influence of this medication"
        return 1
    else
        /bin/rm $@
    fi
}

Хорошо то, что это только Bash.

В такой форме он явно недостаточно общий, но я думаю, что у него есть потенциал, поэтому, пожалуйста, отправьте несколько идей или комментариев.

Обнаружены некоторые псевдонимы безопасности для других команд, чтобы предотвратить подобные катастрофы. Вот:

# safety features
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -I'                    # 'rm -i' prompts for every file
alias ln='ln -i'
alias chown='chown --preserve-root'
alias chmod='chmod --preserve-root'
alias chgrp='chgrp --preserve-root'

Обратите внимание на верхний регистр -I, это отличается от -i:

запросить один раз перед удалением более трех файлов или при рекурсивном удалении. Менее навязчивый, чем -i, но при этом обеспечивает защиту от большинства ошибок

Снаружи chattr, не существует особых гарантий, позволяющих root запускать такую ​​команду. Вот почему правильные группы и осторожные команды важны при работе с привилегиями.

В следующий раз; выделите файлы, которые вы планируете удалить - опустите 'f' из rm -rf, или используйте find и передайте это xargs rm

Просто используйте ZFS для хранения файлов, необходимых для защиты от случайного удаления, и получите демон, который:

  • регулярно делает снимки этой файловой системы
  • удаляет старые / ненужные снимки.

Если файлы были удалены, перезаписаны, повреждены или что-то еще, просто откатите файловую систему до клона последнего удачного снимка, и все готово.

Кроме того, не в качестве меры предосторожности, а как способ узнать, какие файлы были удалены до того, как вы нажмете ^ C, вы можете использовать locate база данных (конечно, только если она была установлена ​​и выжила rm)

Я узнал об этом из этого Сообщение блога

Хе-хе (непроверено и несколько шутливо!):

$ cat /usr/local/bin/saferm

#! /bin/bash

/bin/ls -- "$@"

echo "Those be the files you're about to delete."
echo "Do you want to proceed (y/N)?"

read userresponse

if [ "$userresponse" -eq "y" ]; then

  echo "Executing...."
  /bin/rm -- "$@"

fi

А потом:

alias rm="/usr/local/bin/saferm"

На самом деле, у вас должна быть мысленная пауза перед выполнением такого рода операции с глобусом, независимо от того, работаете ли вы как root, добавляя к нему «sudo» и т. Д. Вы можете запустить «ls» для того же глобуса и т. Д., но мысленно вам следует остановиться на секунду, убедиться, что вы напечатали то, что вы хотели, убедиться, что то, что вы хотите, на самом деле то, что вы хотите, и т. д. Unix SA, точно так же, как hot burner - хороший учитель, говорящий вам, что что-то на плите может быть горячим.

И убедитесь, что у вас есть хорошие резервные копии!

не столько ответ, сколько совет, я всегда делаю rm (dir) -rf не rm -rf (dir) то есть: не переходите к ядерной программе до последнего момента.

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

Я просто написал свой собственный сценарий, который может просто предупреждать и запрашивать подтверждение для любой ситуации, только вам решать, как его улучшить.

#!/bin/sh
# just sudo mv /usr/bin/rm to /usr/bin/rm-original

path=${!#}

color_yel="\x1b[1;33m"
color_rst="\x1b[0m"

function get_yn() {
    read i
    if [ "$i" != "y" ]; then echo "aborted."; exit 1; fi
}

if [ -d ${path} ]; then
    echo -e "${color_yel}You are deleting a folder, it's potentially dangerous, are you sure (y/n) ?${col>
    get_yn
    /usr/bin/rm-original $@
fi

Дальнейшая идея по его улучшению:

  • проверьте определенные флаги и пути
  • переместить в корзину и удалить
  • вылейте старые вещи в корзину через некоторое время

Таким образом, простой настраиваемый скрипт позволяет иметь любое особое поведение и избегать установки дополнительных пакетов.

Обладая некоторыми знаниями о bash, вы можете удалять только определенные вещи.