29

Намерение:

rm -rf string*

Проблема:

rm -rf string *

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

11 ответов11

47

Там нет никакого способа, чтобы полностью пуленепробиваемые системы. И добавив "Вы уверены?«побуждение к вещам является и контрпродуктивным, и приводит к« конечно, я уверен ».

Уловка, которую я подхватил из книги прошлых лет, заключается в том, чтобы сначала выполнить ls -R blah* затем выполнить rm -fr blah* тогда и только тогда, когда список, в который я попал, попал в то, что я хотел.

Достаточно просто сначала выполнить команду ls , а затем , удалить ls -R и заменить на rm -fr .

Последний вопрос: «Если информация была для вас полезной, где ваша резервная копия?"

37

Ловушка DEBUG может быть написана для отмены подозрительных команд. Следующее или похожий на него код можно добавить в ваш ~/.bashrc:

shopt -s extdebug
checkcommand() {
  if [[ $BASH_COMMAND = 'rm -r'*' *' ]]; then
    echo "Suppressing rm -r command ending in a wildcard" >&2
    return 1
  fi
  # check for other commands here, if you like
  return 0
}
trap checkcommand DEBUG

Отрегулируйте логику по вкусу.

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

8

Можете ли вы научиться использовать, например, rmrf вместо rm -rf?

Если это так, эта функция bash предоставит вам шанс увидеть, что на самом деле произойдет, прежде чем подтвердить команду:

rmrf() { echo rm -rf "$@"; read -p "Proceed (y/N)? "; [ "${REPLY,,}" = y ] && rm -rf "$@"; }

Чтобы сделать эту функцию постоянной, добавьте эту строку в файл ~/.bashrc на каждом используемом компьютере.

Сравнение с общим псевдонимом rm

Обычно называют псевдоним:

alias rm='rm -i'

Это имеет два ограничения:

  1. Если вы зависите от этого псевдонима, то вы будете шокированы, когда находитесь на машине или в среде, где ее нет. Напротив, попытка запустить rmrf на машине без этой функции вернет безобидную command not found .

  2. Этот псевдоним в вашем случае не поможет, потому что опция -f указанная вами в командной строке, переопределяет опцию -i в псевдониме.

6

Если я нахожусь в ситуации, когда удаление неправильных файлов является действительно серьезным делом, одна из вещей, которые я сделал, - это создание папки для мусора, такой как mkdir trashcan , и затем у меня есть скрипт rmTrashcan котором есть rm -rf trashcan/* или rm -rf * или аналогичные, написанные очень тщательно и проверенные несколько раз.

Таким образом, если я сделаю ошибку, ошибка будет в команде mv , а не в команде rm . После того , как я выполнил команду ls и уверен в том, что именно я удаляю , rmTrashcan действительно выполняет грязную работу безопасно.

Это также было чрезвычайно удобно для ситуации, когда мне приходилось удалять резервные копии. Я мог mv целый месяц резервных копий в мусорную корзину, mv несколько немногих я хотел сохранить (1-го числа, 15-го числа месяца) обратно в резервные копии, затем rmTranshcan остальное. Выполнение аналогичной команды трудно сделать с rm самостоятельно, и делать это таким образом , позвольте мне ls резервные копии , чтобы быть уверенным в том, что файлы я оставляю позади (а не просто перечислять файлы я намерен удалить)

4

Вместо того, чтобы возиться с двумя командами (ls и rm), я думаю, что проще и проще использовать find:

find . -maxdepth 1 -name "string*" -delete

Если вы случайно наберете "string *" он удалит файлы с именами string chars и string letters (что в любом случае вам и нужно), но он не будет захватывать все файлы, такие как * в оболочке.

Кроме того, вы можете -delete чтобы увидеть, какие файлы он будет удалять, затем нажать стрелку вверх и набрать -delete проще, чем набирать ^ls -R^rm -rf или другие глупости.

3

Есть ли простой способ разумной защиты от случайного трейлинга или лидирующего символа подстановки?

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

Это означает, что все это проблема пользовательского интерфейса, даже если он находится на уровне текстовой / командной строки. Сколько сетей безопасности вы ожидаете, чтобы защитить вас от того, что вы не должны делать? Это как ножницы: если вы как-то небрежны, поскользнулись и порезали руку, намереваясь порезать ткань или бумагу, кто виноват? Или даже светофоры и знаки остановки: на самом деле ничто не мешает водителю включить свет или игнорировать дорожные знаки, кроме острой осведомленности о том, что может случиться, если они действительно будут вести себя так рискованно.

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

Если вы работаете в системе, в которой вы единственный, кто имеет к ней доступ, у вас может возникнуть соблазн просто chmod 777 , но это не тот способ, которым настроена рациональная система. Вместо этого разрешения должны быть примерно 755 для всех каталогов и 644 для всех неисполняемых файлов. Размер исполняемых файлов должен быть не менее 755 , но, возможно, даже 744 если вы хотите, чтобы другие читали, но не запускали файлы.

2

У rm есть флаги -i и -I для подтверждения перед каждым удалением. В прошлом некоторые дистрибутивы включали их по умолчанию. Это ужасная идея. Дайте пользователю слишком много диалогов подтверждения для нормальной работы, и они начнут их обычное подтверждение. Это просто сдвигает требование "быть осторожным" (всегда красным флажком) в новый и более раздражающий диалог. "Да. Да. Да. Да! ДА! Черт возьми, тупой компьютер, просто удали файлы YESYESYESYESYES - CRAP, я не имею в виду! NOOOOOOO!«Это проблема диалога« Да, но я имел в виду нет ». Этот ответ дает наглядное объяснение того, почему диалоги подтверждения приходят не вовремя.

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

Существуют различные системы мусора для Unix, и этот ответ полон предложений.

Вопрос в том, чтобы псевдоним rm или нет в псевдоним rm. Плюсы для алиасинга рм ...

  1. Вы не можете забыть об использовании альтернативы rm.

Минусы для псевдонимов ...

  1. Вы можете полагаться на это в системах, в которых этого нет.
  2. Может вызвать проблемы, когда диск почти заполнен.
  3. Нужна инфраструктура, чтобы периодически очищать мусор.
  4. Должны быть уверены, что не мешают ожидаемому поведению rm в программах.
  5. Может не полностью подражать рм.

Если вы будете следовать первому аргументу слишком далеко, вы будете использовать vi (не vim, vi), csh (не tcsh, csh) и другие устаревшие утилиты, потому что они доступны повсеместно. Тем не менее, существует опасность перенастройки вашей среды. Я предпочитаю брать с собой свои коммунальные услуги и делать это как можно проще. YMMV.

Два и три являются техническими проблемами. Они могут быть решены с помощью умного жнеца, который проверяет размер мусора и периодически убирает вещи, как в случае с жнецом. Это может быть задание cron или более умная версия, в которой можно использовать различные инфраструктуры событий файловой системы, доступные во многих дистрибутивах Linux для настольных компьютеров. Это не просто, а еще сложнее сделать эффективно. Лучше найти существующую систему, чем пытаться создать собственную.

С четвертым можно разобраться, сделав ваш новый rm псевдонимом оболочки, alias rm='trash' , тогда это не повлияет на программы.

Пятая проблема, которую я оставляю читателю для решения. У rm не так много переключателей.

2

Я учу всех о !$ = последний аргумент в последнем командном приеме:

% ls job[XYZ].*
jobX.out1
jobX.out2
[rest of the matches]

% rm !$

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

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

Техник в моей лаборатории только что сделал эту ошибку на прошлой неделе (3 месяца работы) - и да, у нас была резервная копия (1 день позади).

2

Попробуйте составить исходную команду rm без флага -f , но вместо этого с -i , так что rm будет запрашивать каждый файл, который он намеревается удалить. Для небольших рекурсивных удалений вы можете удерживать клавишу y , как только вы убедитесь, что команда была введена правильно. Для больших удалений вы можете прервать операцию и использовать историю командной строки, чтобы аккуратно изменить -i на -f .

0

Кажется, все говорят: "Будь осторожнее", «Не делай подсказок с псевдонимом / подтверждением, потому что ты привык не обращать на это должного внимания».

Круто и все. Я имею в виду, я не думаю, что вы должны создавать псевдоним для rm (ни для rmrf , так как вы можете легко это испортить и набрать настоящую команду).

Но почему вы не можете создать псевдоним / скрипт и вызвать его, скажем, remove и передать только один аргумент (например, $ 1)? Подстановочный знак должен быть $ 2 из-за непреднамеренного пробела (amiright?) и, таким образом, ваш скрипт / оболочка / псевдоним не будет передан второму. Да, вы можете делать только один набор удалений (с подстановочным знаком), но это цена, которую вы заплатите.

Если бы я писал что-то хорошее, я мог бы попросить сообщить мне количество файлов и каталогов, которые он планирует удалить, и общий размер удаляемых материалов, а затем попросить подтвердить, но это может помешать вашему потоку. Может быть, сделать эту опцию флага на remove? (-я). Вы также можете сделать проверку $ 1, чтобы увидеть, является ли это просто одним символом подстановки, запросить подтверждение и указать, в каком каталоге вы находитесь.


Кроме того, существует ряд замен rm . Многие пытаются быть совместимыми с мусором рабочего стола пользовательского интерфейса. Некоторые из них, возможно, стоит изучить.

0

Очень простой трюк - поставить в конце -rf : rm whatever* -rf
Это значительно снижает частоту появления ошибок, потому что вы набираете больше символов после * , поэтому у вас больше времени, чтобы увидеть опечатки.
Это не все решает. Просто простой ежедневный трюк.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .