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

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

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


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


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

29 ответов

Решение

Один из приемов, которым я следую, - это поставить # в начале при использовании 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)

ИЛИ ЖЕ

Используйте Safe-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 неправильный каталог.

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

Лучшие решения включают изменение ваших привычек не использовать 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"

Вы также можете интегрировать его с клиентом командной строки для твиттера, чтобы предупредить своих друзей о том, что вы почти унижаете себя, вытирая жесткий диск 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 зеркально отразить код и сохранить историю на другой машине. Если вы работаете с документами, есть сценарий, который rsyncВаши документы на другую машину.

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

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

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

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

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

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

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

mkdir /tmp/recyclebin

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

mv target_folder /tmp/recyclebin

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

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

Задавать noclobber предотвращать mv а также cp от уничтожения файлов тоже.

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

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

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

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

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

Мой процесс удаления на 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 команда, то, что произошло со мной, прежде чем я начал следовать этому процессу.

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

Если у вас нет настроения приобрести новые привычки прямо сейчас, .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.

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

В случае, если это помогает кому-то для их собственного случая:

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

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

# 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

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

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

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

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

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

введите описание здесь

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

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

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

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

Готово.

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

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

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

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

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

$ 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, так же, как горячая горелка - хороший учитель, который говорит вам, что что-то на плите может быть горячим.

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

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

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

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

Я узнал об этом из этого поста в блоге

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

https://unix.stackexchange.com/questions/379138/aliasing-rm-to-create-a-cli-recycle-bin

Другие вопросы по тегам