Czy mogę uczynić `rm` interaktywnym tylko podczas korzystania z globowania? (w bash, zsh lub w obu)

15

Ilekroć mam rmkilka przedmiotów naraz z globowaniem skorupy i istnieje nawet najmniejsza możliwość, że wzór rozszerzy się bardziej niż się tego spodziewam, zawsze staram się pamiętać o dodaniu -i, ale (oczywiście) mogłem zapomnieć i przypadkowo zdmuchnąć coś pożytecznego. Niektórzy próbują rozwiązać ten problem za pomocą aliasu, na przykład alias rm='rm -i'nie podoba mi się pomysł, aby rm zawsze był interaktywny, ponieważ wtedy nabiorę nawyku korzystania z niego przez -fcały czas, co oczywiście pokona cały cel.

To, co chciałbym zrobić, to rmużywać tylko -iwtedy, gdy używam globowania, i -foczywiście w celu zastąpienia -i, więc nadal mogę wymazać całe katalogi ze zwykłymi rm -rf junk.

Dlatego rm *blah*naprawdę byłoby, rm -i *blah*ale rm blahdziałałoby dokładnie tak, jak na maszynie.

W przypadku różnicy, w jaki sposób można to osiągnąć w różnych powłokach, wybiorę odpowiedź, która dostarcza metody zarówno dla bash, jak i zsh, zamiast odpowiedzi, które obejmują tylko jedną lub drugą.


Uwaga : tak naprawdę nie jestem przekonany, że to koniecznie dobry pomysł; Pytam tylko, czy to możliwe. Jeśli uważasz, że to głupi pomysł, byłbym bardzo szczęśliwy, słysząc uzasadnienie twojej opinii, ale proszę nie zamieszczaj takich komentarzy w polu odpowiedzi . Prawdziwe odpowiedzi albo mówią mi, jak to zrobić, albo wyjaśniają, że / dlaczego nie jest to możliwe (lub ewentualnie oferują alternatywną metodę uzyskania podobnego wyniku). Ale jeśli chcesz mi powiedzieć, dlaczego to jest głupie, napisz jako komentarz. Głosuję za uzasadnionymi komentarzami, nawet jeśli nie zgadzam się z wnioskiem.

ikonoklasta
źródło
7
Kilka sugestii: z narzędziami GNU rm -Ijest tak, -iże uruchamia się tylko wtedy, gdy -rzostaną przekazane więcej niż trzy pliki . W bashużyj Ctrl-x *skrótu klawiaturowego, aby rozwinąć glob i sprawdzić go sam.
jw013,
2
W przypadku bash uważam, że odpowiedź brzmi „nie”. Z zsh możesz być w stanie skorzystać noglobnp. Z aliasingu rm do noglob my-rm, a następnie mając my-rm jako skrypt, który sprawdza glob, rozwija go i przekazuje -i lub nie. Nie jestem pewien, nie znam Zsh.
derobert
@derobert: na pewno brzmi jak wiesz zsh całkiem dobrze.
iconoclast
@iconoclast Nie, nie zsh, tylko Google. Dziwnie, odkryłem, że próbując znaleźć sposób na zrobienie tego w bashu. :-P
derobert
Jeśli chcesz czegoś, co wygląda jak rm, ale faktycznie działa inaczej, powinienem napisać skrypt (lub alias / klawisz funkcyjny / funkcyjny) myrmi pozwolić temu skryptowi robić to, co lubisz.
Walter A

Odpowiedzi:

9

To nie jest łatwe. Problem polega na tym, że kiedy:

rm -- *.txt

rm widzi tylko listę plików, a nie wzorzec globowania, który został już rozwinięty przez powłokę.

Co możesz zrobić to (zsh):

alias rm='noglob rm'

Mówi to zsh, że wzorce nie powinny być rozszerzane podczas wywoływania rm. Następnie możesz ponownie zdefiniować rm jako funkcję, która dokonuje samego rozszerzenia i dodaje „-i”, jeśli zajdzie taka potrzeba:

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

Problem z tym podejściem polega jednak na tym, że ten nowy „rm” nie widzi różnicy między

rm *

i

rm '*'

Aby usunąć plik o nazwie *, musisz go zapisać:

rm [*]
Stéphane Chazelas
źródło
-1

Działa w trybie bash, prawdopodobnie w innych powłokach. Umieść w swoim.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
źródło
3
Możesz użyć, command rmaby uniknąć zakodowania na stałe PATH. Podejście polegające na sprawdzaniu liczby argumentów jest nieco niewiarygodne, ponieważ rmmoże to wymagać opcji.
jw013,
1
Należy podać „$ 1”, inaczej to się nie powiedzie, jeśli pojedynczy plik zawiera spację. @ jw013 - Możesz także uciec od polecenia, np.\rm
jordanm
@jordanm Masz rację co do potrzeby cytowania $1z podwójnymi cudzysłowami, ale źle o ucieczce polecenia. Cytując tylko pomija aliasy, NIE wyszukiwanie funkcji. Ta odpowiedź sugeruje funkcję, a nie alias.
jw013,
1
Przynajmniej stara edycja działała - nowa edycja odrzuca opcje wiersza poleceń użytkownika, co prawdopodobnie nie jest właściwe.
jw013,
@ jw013 - Nie wiedziałem, że działa tylko w przypadku wyszukiwania aliasów, a nie funkcji. Dzięki za informację.
jordanm