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

164

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

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


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


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

Валентин Немцев
источник
13
К вашему сведению, вы также можете сделать rm -rf . /mydirвместо rm -rf ./mydirи убить любой каталог, в котором вы были. Я считаю, что это происходит чаще.
user606723
27
Если использовать аналогию с пистолетом, этот вопрос говорит: «Пожалуйста, сделайте так, чтобы пистолет распознал, что я нацеливаюсь на свою ногу, а не на огонь, но я не хочу нести никакой ответственности за то, что я не нацелил оружие на мою ногу. Оружие и компьютеры глупы, и если вы сделаете глупость, вы получите эти результаты. Следуя аналогии с оружием, ничто не удержит вас от причинения себе вреда, кроме бдительности и практики.
slillibri
73
@slillibri За исключением того, что rmэто не пистолет, это компьютерная программа, она может быть достаточно умной, чтобы определить, что пользователь собирается удалить некоторые важные файлы и выдать предупреждение (как на самом деле, если вы пытаетесь обойтись rm -rf /без звездочки).
Валентин Немцев
80
У @slillibri есть оружие. Вопрос о том, как повысить безопасность rmкоманды, является вполне законным вопросом сисадмина.
Жиль
21
sudo rm / bin / rm не рекомендуется, но предотвратит большинство rm :-)
Paul

Ответы:

220

Один из приемов, которым я следую, заключается в том, чтобы #в начале использовать 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
Sachin Divekar
источник
10
safe-rm выглядит очень хорошо, глядя на это сейчас ...
Валентин Немцев
45
Safe-RM это аккуратно. Также это отличный трюк с -iфайлом. Хах. Глупый удар
EricR
5
Удивительно, что за хитрость делается в Unix.
WernerCD
4
Создаваемый файл с именем -i абсолютно чистый гений. Я мог бы использовать это около года назад, когда случайно запустил rm -rf / etc / * на VPS ... (к счастью, я делаю ночные снимки, поэтому смог восстановить менее чем за 45 минут).
Дэвид W
9
Это гений. Колдовство будетtouch -- -rf
Мирча Вутковичи
46

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

Я просто случайно запустил 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установлены? Эти инструменты являются опорой, и гораздо лучше полагаться на известные значения по умолчанию и улучшить свои рабочие привычки.

Стефан Ласевский
источник
19
Мой друг сказал мне, что он никогда не использует rm -rf *. Сначала он всегда меняет каталог и использует конкретную цель. Причина в том, что он часто использует историю оболочки, и его беспокоит, что такая команда в его истории может появиться в неподходящее время.
haggai_e
@haggai_e: Хороший совет. Когда я был новичком в Unix, я побежал один раз столкнулся с ошибкой, где rm -rf *также удалены .и ... Я был root, и это перешло в нижние каталоги вроде ../../.., и было довольно разрушительным. С rm -rf *тех пор я стараюсь быть очень осторожным .
Стефан Ласевский
2
rm -rf $FOOне поможет , если вам нужно rm -rf $FOO/$BAR. cd $FOO && rm -rf $BARпоможет, хотя это намного дольше.
Виктор Сергиенко
5
@VictorSergienko, с bash, как насчет указания ${FOO:?}, как в rm -rf ${FOO:?}/и rm -rf ${FOO:?}/${BAR:?}. Это предотвратит его когда-либо перевести на rm -rf /. У меня есть больше информации об этом в моем ответе здесь .
Acumenus
@haggai_e: Я считаю это одним из лучших советов по этой теме. Я сжег свой палец, используя rm -rf *цикл for, который по ошибке изменился на неправильный каталог и в итоге удалил что-то еще. Если бы я использовал конкретную цель, у нее был бы гораздо меньший шанс удалить не ту вещь.
Ричк
30

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

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

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

Не сейчас
источник
4
И вы должны использовать виртуальную машину или запасную коробку, чтобы попрактиковаться в восстановлении - выясните, что не сработало, и уточните указанный план. Мы входим в двухнедельную перезагрузку - потому что в нашем здании были перебои в подаче электроэнергии, и каждый раз это было болезненно. Сделав несколько запланированных остановок всех стоек, мы сократили его с нескольких дней бега до примерно 3 часов - каждый раз, когда мы узнаем, какие биты нужно автоматизировать / исправить сценарии init.d и т. Д.
Дэнни Стейпл
И попробуйте эту команду на виртуальной машине. Это интересно! Но сначала сделайте снимок.
Стефан Ласевский
23

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

жилль
источник
mv -t DELETE_ME -- *немного более надежный
Тобу
@Giles Непосредственное использование rm- это хороший совет! Еще лучшей альтернативой является использование findкоманды .
aculich
И если вам нужно, чтобы каталог оставался, вы можете сделать это довольно просто, используя find somedir -type f -deleteкоторый удалит все файлы в нем, somedirно оставит каталог и все подкаталоги.
aculich
19

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

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 /*правами root.

Нафтули Кей
источник
3
+1 за телнет miku.acm.uiuc.edu
Али
1
псевдоним echo = "telnet miku.acm.uiuc.edu"
kubanczyk
Я не должен быть достаточно старой школы ... в чем смысл telnet miku.acm.uiuc.edu?
Кайл Стрэнд
Попробуйте и узнайте. Это не разрушительно. Если вы параноик, как и должно быть, запустите виртуальную машину.
Нафтули Кей
3
-1 Вы не можете использовать псевдонимы команд с пробелами, не говоря уже о / *, что является недопустимым именем
xenithorb
15

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

Кроме того, посмотрите на что-то вроде https://launchpad.net/safe-rm .

Свен
источник
Упоминается работа от имени root в редакторе
Валентин Немцев
@Valentin: о_О !!
Джонатан Риу
15

Самый простой способ предотвратить случайное использование 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.

aculich
источник
Очень интересная дискуссия. Мне нравится твой подход и сделан небольшой фрагмент. Это супер неэффективно, так как он вызывает find не более 3 раз, но для меня это хорошее начало: github.com/der-Daniel/fdel
Даниэль Хитцель
14

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

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

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

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

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

просмотр_события
источник
2
+1 за использование ls.
Сачин Дивекарь
@eventi Я согласен, что в этой ветке есть несколько ужасных советов и ужасных хаков. И это определенно хорошая идея, чтобы посмотреть на что-то, прежде чем уничтожить это, но есть еще лучший способ сделать это с помощью findкоманды .
aculich
Я не вижу, как найти проще или безопаснее, но мне нравится ваш find . -name '*~'пример. Я lsхочу сказать, что в списке будет тот же глобус, который rmбудет использовать.
Eventi
11

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

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

Безумный Шляпник
источник
2
Пожалуйста, сравните: linuxmanpages.com/man3/regex.3.php linuxmanpages.com/man3/glob.3.php
bukzor
5
ОК, что я ищу? Вы подчеркиваете, что синтаксис регулярного выражения для сопоставления файлов отличается (и иногда называется другим именем) от синтаксиса, используемого, например, в perl? Или какой-то другой момент, который я пропустил? Я извиняюсь за медлительность своих мыслей, это первое, что здесь происходит в субботу утром!
MadHatter
9
Эти вещи, которые вы называете "регулярное выражение", на самом деле глобусы. Это не другой синтаксис регулярных выражений; это не регулярное выражение
Букзор
1
Этот аргумент, безусловно, может быть сделано; однако из статьи в Википедии о регулярных выражениях я нахожу, что «многие современные вычислительные системы предоставляют символы подстановки в соответствующих именах файлов в файловой системе. Это основная возможность многих оболочек командной строки и также известна как глобализация» - обратите внимание на использование «также известного как», которое, как мне кажется, указывает на то, что вызов токенов, содержащих метасимволы, для совпадения с одним или несколькими регулярными выражениями имен файлов не является неправильным. Я согласен с тем, что глобирование является лучшим термином, потому что оно не означает ничего, кроме использования регулярных выражений в сопоставлении имен файлов.
MadHatter
1
@MadHatter Кроме того, globbing, хотя и визуально чем-то похожий, семантически сильно отличается от регулярных выражений. В регулярном выражении значение *имеет очень точное определение, называемое Клини Стар, который является унарным оператором, который соответствует нулю или нескольким элементам набора, к которому он применяется (в случае регулярных выражений, символ или набор символов, предшествующий Kleene Star), в то время как в шарлатанстве *совпадает все, что в схеме, которая следует. Они семантически сильно отличаются, даже если они имеют похожий синтаксис.
aculich
9

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

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

Дэвид Шварц
источник
Также может помочь файловая система копирования при записи, такая как btrfs. Вы можете легко настроить простой автоматический поворот снимка, который выполняется локально (в дополнение к внешнему резервному копированию).
Мальта
6

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

Одной из таких утилит, трэш-кли, обсуждается на Unix StackExchange, здесь .

nnutter
источник
Это первое, что я устанавливаю на каждую машину. Это должен быть инструмент удаления по умолчанию, при этом rm используется только тогда, когда вам нужно что-то удалить прямо сейчас. Мне грустно, что это еще не сняло, но однажды это будет. Вероятно, после очень открытого экземпляра rm, вызвавшего огромную проблему, которая не могла быть решена резервными копиями. Вероятно, что-то, где время, необходимое для восстановления, играет огромную роль.
Джерри
+1 После использования Linux в течение 20 лет я все еще думаю, что должно быть какое-то поведение для мусорной корзины rm.
Шовас
3

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

Халед
источник
4
Я не уверен, что sudo предотвратит что-то подобное. Вы можете сделать ту же опечатку, что и OP, даже если вы наберете «sudo» перед «rm».
CJC
1
Упоминается работа от имени root в редакторе
Валентин Немцев
Если вы все еще не уверены в использовании sudoи резервном копировании. Посмотрите на эту страницу: forum.synology.com/wiki/index.php/… . Это говорит о создании корзины. Надеюсь это поможет!
Халед
1
@Khaled Я использую sudo и резервные копии, я просто хочу что-то лучшее для этой конкретной проблемы
Валентин Немцев
3

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

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

Wyzard
источник
2

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

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

Rilindo
источник
2

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

Установите, noclobberчтобы предотвратить mvи cpуничтожить файлы тоже.

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

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

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

Андрей Паньков
источник
+1 за использование какого-либо метода предварительного просмотра ваших файлов перед их удалением, однако есть более простые и безопасные способы сделать это с помощью findкоманды .
aculich
2

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

математический
источник
1

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

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

тонкий лед
источник
Хорошо, что вы предлагаете использовать find, но я рекомендую более безопасный способ использования в моем ответе . Нет необходимости использовать, xargs rmпоскольку все современные версии findимеют -deleteопцию . Кроме того , чтобы безопасно использовать xargs rmвам также нужно использовать find -print0и в xargs -0 rmпротивном случае вы будете иметь проблемы , когда вы сталкиваетесь вещи , как имена файлов с пробелами.
aculich
Моя точка зрения касалась не нюансов о xargs, а скорее использования поиска сначала, без удаления файлов, а затем продолжения ..
thinine
Да, я думаю, что определение области использования файлов findявляется хорошим предложением, однако нюансы xargsважны, если вы предлагаете использовать его, в противном случае это приводит к путанице и разочарованию при обнаружении файлов с пробелами (чего можно избежать с помощью этой -deleteопции).
aculich
1

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

# 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, но при этом защищает от большинства ошибок

Валентин Немцев
источник
Хотя опция I не будет отражать то, что вы собираетесь удалить.
Кальмариус
1

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

a3nm
источник
1

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

Мохит Ранка
источник
Предварительный просмотр файлов перед их удалением - это хорошая идея, и есть еще более безопасный и выразительный способ сделать это, используя, find как я объясняю в своем ответе .
aculich
1

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

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

KLN
источник
Хорошо, что вы пытаетесь предварительно просмотреть свои файлы перед их удалением, однако это решение слишком сложное. Вместо этого вы можете выполнить это очень просто более общим способом, используя findкоманду . Кроме того, я не понимаю, почему вы говорите, что «хорошо, что это только Bash»? Рекомендуется избегать ошибок в сценариях .
aculich
Чтобы запретить нам использовать «rm -rf / *» или «rm -rf dir / *», когда мы имеем в виду «rm -rf ./*» и «rm -rf dir / *», мы должны обнаружить шаблоны «/ *» и "*" (упрощенно). Но мы не можем просто передать все аргументы командной строки через grep в поисках какого-либо вредоносного шаблона, потому что bash расширяет аргументы с подстановочными знаками перед их передачей (звезда будет расширена до всего содержимого папки). Нам нужна строка необработанного аргумента. Это делается с помощью set -f, прежде чем мы вызовем функцию «myrm», которая затем передается необработанной строке аргумента, и grep ищет предопределенные шаблоны. *
KLN
Я понимаю, что вы пытаетесь сделать, set -fчто эквивалентно set -o noglobв Bash, но это все еще не объясняет ваше утверждение, что «хорошо в этом то, что это только Bash». Вместо этого вы можете устранить проблему полностью и в общем виде для любой оболочки, не используя rmвообще, а скорее используя findкоманду . Вы действительно попробовали это предложение, чтобы увидеть, как оно сравнивается с тем, что вы предлагаете здесь?
aculich
@aculich только bash Я имею в виду отсутствие питона или perl-зависимостей, все можно сделать в bash. Как только я исправлю свой .bashrc, я смогу продолжать работать, не избавляясь от старых привычек. Каждый раз, когда я вызываю rm bash, я не буду делать глупостей. Я просто должен определить некоторые шаблоны, о которых я хочу быть предупрежден. Как и «*», который удаляет все в текущей папке. Время от времени это будет именно то, что я хочу, но с немного большей интерактивностью работы можно добавить к «myrm».
KLN
@aculich Хорошо, понял. Нет, я не пробовал. Я думаю, что это требует значительных изменений в рабочем процессе. Только что проверил здесь, в Mac OS X, моя .bash_history - 500, и 27 из этих команд - rm. И в наши дни я не очень часто пользуюсь терминалом.
клн
1

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

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

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

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

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

введите описание изображения здесь

Майлз Вольбе
источник
1

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

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

mkdir /tmp/recyclebin

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

mv target_folder /tmp/recyclebin

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

Базилик А
источник
0

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

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

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

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

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

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

Валентин Немцев
источник
0

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

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

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

jlliagre
источник
0

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

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

Sirex
источник
Умный, но не будет работать на BSD rm, где параметры должны предшествовать именам файлов.
svenper
да уж. Я узнал об этом недавно с помощью Apple. Исправление состоит в том, чтобы установить инструменты gnu и установить псевдонимы для всего :) и / или предпочтительно выбросить яблоко в мусорную корзину. :)
Sirex
1
если бы мне разрешили, я бы сделал это за наносекунду. Это мусор по сравнению с Linux.
Sirex
0

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

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

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

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

Готово.

Джонни Вонг
источник
0

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

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

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

$ rmsafe /path/to/important/files

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

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

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

$ 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

Alexar
источник