Могу ли я сделать `rm` интерактивным только при использовании globbing? (либо в bash, либо в zsh, либо в обоих)

15

Всякий раз, когда я делаю rmнесколько элементов одновременно с использованием оболочки, и существует даже малейшая вероятность того, что шаблон расширяется до большего, чем я ожидаю, я всегда стараюсь не забыть добавить -i, но (конечно) я могу забыть и случайно выбросить что-нибудь полезное. Некоторые люди пытаются решить эту проблему с помощью псевдонима, например, alias rm='rm -i'но я ненавижу идею сделать rm всегда интерактивным, потому что тогда я привыкну использовать -fвсе время, что, очевидно, победит всю цель.

То, что я хотел бы сделать, это rmиспользовать только -iтогда, когда я использую globbing, и, -fконечно, для переопределения -i, так что я все еще могу сносить целые каталоги обычным способом rm -rf junk.

Поэтому rm *blah*действительно будет, rm -i *blah*но rm blahбудет работать точно так, как напечатано.

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


Примечание : я не уверен, что это хорошая идея; Я просто спрашиваю, возможно ли это. Если вы думаете, что это глупая идея, я был бы очень рад услышать обоснование вашего мнения, но, пожалуйста, не размещайте такие комментарии в поле для ответов . Реальные ответы либо говорят мне, как это сделать, либо объясняют, что / почему это невозможно (или, возможно, предлагают альтернативный метод для получения аналогичного результата). Но если вы хотите сказать мне, почему это глупо, пожалуйста, оставьте комментарий. Я буду одобрять аргументированные комментарии, даже если я не согласен с заключением.

иконоборец
источник
7
Несколько предложений: с утилитами GNU, rm -Iэто похоже на -iто, что срабатывает только когда -rпередается более трех файлов . В bash, используйте Ctrl-x *сочетание клавиш, чтобы развернуть шар и проверить его самостоятельно.
jw013
2
С Bash я считаю, что ответ «нет». Используя zsh, вы можете воспользоваться преимуществами noglob, например, присвоить псевдониму rm noglob my-rm, а затем иметь my-rm скрипт, который проверяет глобус, расширяет его и передает -i или нет. Не уверен, не знаю, зш.
Дероберт
@derobert: вы , конечно , звучит , как вы знаете , ЗШ довольно хорошо.
иконоборчество
@iconoclast Нет, не Zsh, просто Google. Как ни странно, я обнаружил это при попытке найти способ сделать это в bash. :-P
Дероберт
Если вам нужно что-то, похожее на rm, но на самом деле работающее по-другому, я должен написать скрипт (или псевдоним / функция / функциональная клавиша) с именем myrmи позволить этому скрипту делать то, что вам нравится.
Уолтер А

Ответы:

9

Это не легко. Проблема в том, что когда вы делаете:

rm -- *.txt

rm просто видит список файлов, а не шаблон смещения, который уже был расширен оболочкой.

Что вы могли бы сделать, это (zsh):

alias rm='noglob rm'

Это говорит zsh, что шаблоны не должны раскрываться при вызове rm. Затем вы можете переопределить rm как функцию, которая сама выполняет расширение и добавляет «-i», если необходимо, что-то вроде:

'rm'() {
  [[ "$*" = *[*[?]* ]] && set -- -i "$@"
  command rm $~@
}

Проблема с этим подходом заключается в том, что этот новый «рм» не видит разницы между

rm *

и

rm '*'

Чтобы удалить вызванный файл *, вам нужно написать его:

rm [*]
Стефан Шазелас
источник
-1

Работает в bash, возможно в других оболочках. Место в вашем.bashrc

function rm() { 
  while test "${1:0:1}" = "-"; do 
    shift
  done
  if test $# -eq 1; then 
    command rm "$1"
  else 
    command rm -i "$@"
  fi
}
doneal24
источник
3
Вы можете использовать, command rmчтобы избежать жесткого кодирования PATH. Кроме того, подход проверки количества аргументов немного ненадежен, так как rmможет принимать варианты.
jw013
1
«1 $» следует заключить в кавычки, иначе это не удастся, если в одном переданном файле будет пробел. @ jw013 - Вы также можете избежать команды, например,\rm
Иордания
@jordanm Вы правы насчет необходимости заключать в кавычки $1двойные кавычки, но ошибаетесь в отношении экранирования команды. Цитирование только подавляет псевдонимы, а НЕ ищет функцию. Этот ответ предлагает функцию, а не псевдоним.
jw013
1
По крайней мере, старое редактирование было функциональным - новое редактирование отменяет параметры командной строки пользователя, что, вероятно, не является правильным решением.
jw013
@ jw013 - я не знал, что работает только для поиска псевдонимов, а не функций. Спасибо за информацию.
Иордания