Puis-je rendre `rm` interactif uniquement lors de l'utilisation du globbing? (en bash ou zsh ou les deux)

15

Chaque fois que je rmmultiplie les éléments à la fois avec l'éclatement de la coquille et qu'il y a même la moindre possibilité que le motif se développe plus que je ne le pense, j'essaie toujours de m'en souvenir -i, mais (bien sûr) je pourrais oublier et emporter accidentellement quelque chose d'utile. Certaines personnes essaient de résoudre ce problème avec un alias, comme alias rm='rm -i'mais je déteste l'idée de rendre rm toujours interactif, car alors j'aurai l'habitude de l'utiliser -ftout le temps, ce qui va évidemment à l'encontre de l'objectif.

Ce que j'aimerais faire, c'est de rmne l'utiliser que -ilorsque j'utilise la globalisation, et -fbien sûr de passer outre -i, afin que je puisse encore emporter des répertoires entiers avec l'habituel rm -rf junk.

Par conséquent, ce rm *blah*serait vraiment, rm -i *blah*mais rm blahfonctionnerait exactement comme tapé.

Au cas où il y aurait une différence dans la façon dont cela pourrait être accompli dans différents shells, je choisirai une réponse qui fournit des méthodes pour bash et zsh plutôt que des réponses qui ne couvrent que l'un ou l'autre.


Remarque : je ne suis pas vraiment convaincu que ce soit nécessairement une bonne idée; Je demande juste si c'est possible. Si vous pensez que c'est une idée stupide, je serais très heureux d'entendre le raisonnement derrière votre opinion, mais veuillez ne pas poster de tels commentaires dans le champ de réponse . Les vraies réponses me disent comment faire cela ou expliquent cela / pourquoi cela n'est pas possible (ou peut-être offrent une méthode alternative pour obtenir un résultat similaire). Mais si vous voulez me dire pourquoi c'est stupide, veuillez poster un commentaire. Je voterai pour des commentaires bien motivés même si je ne suis pas d'accord avec la conclusion.

iconoclaste
la source
7
Quelques suggestions: avec les utilitaires GNU, rm -Ic'est comme -iça qui ne se déclenche que lorsque plus de trois fichiers ou -rsont passés. Dans bash, utilisez le Ctrl-x *raccourci clavier pour développer le glob et inspectez-le vous-même.
jw013
2
Avec bash, je crois que la réponse est "non". Avec zsh, vous pourriez être en mesure, noglobpar exemple, d'aliaser rm en noglob my-rm, puis d'avoir my-rm comme un script qui vérifie un glob, le développe et passe -i ou non. Pas sûr, je ne sais pas zsh.
derobert
@derobert: vous avez certainement l' impression de bien connaître zsh.
iconoclaste du
@iconoclast Non, pas zsh, juste Google. Curieusement, j'ai trouvé cela en essayant de trouver comment le faire en bash. :-P
derobert
Si vous voulez quelque chose qui ressemble à rm mais qui fonctionne réellement différemment, je devrais écrire un script (ou alias / fonction / touche de fonction) appelé myrmet laisser ce script faire les choses merveilleuses que vous aimez.
Walter A

Réponses:

9

Ce n'est pas facile. Le problème est que lorsque vous faites:

rm -- *.txt

rm ne voit que la liste des fichiers, pas le modèle de globalisation qui a déjà été développé par le shell.

Ce que vous pourriez faire est (zsh):

alias rm='noglob rm'

Cela indique à zsh que les modèles ne doivent pas être développés lors de l'appel de rm. Ensuite, vous pouvez redéfinir rm comme une fonction qui fait l'expansion elle-même et ajoute le "-i" si besoin est quelque chose comme:

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

Le problème avec cette approche est que ce nouveau "rm" ne voit pas la différence entre

rm *

et

rm '*'

Pour supprimer le fichier appelé *, vous devez l'écrire:

rm [*]
Stéphane Chazelas
la source
-1

Fonctionne en bash, probablement dans d'autres coquilles. Placer dans votre.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
la source
3
Vous pouvez utiliser command rmpour éviter le codage en dur PATH. De plus, l'approche consistant à vérifier le nombre d'arguments est un peu peu fiable, car elle rmpeut prendre des options.
jw013
1
Le "$ 1" doit être cité, sinon cela échouera si le fichier unique transmis contient un espace. @ jw013 - Vous pouvez également échapper à la commande, par exemple\rm
jordanm
@jordanm Vous avez raison sur la nécessité de citer $1entre guillemets doubles, mais vous avez tort sur l'échappement de la commande. La citation supprime uniquement les alias, PAS la recherche de fonction. Cette réponse suggère une fonction, pas un alias.
jw013
1
Au moins, l'ancienne modification était fonctionnelle - la nouvelle modification ignore les options de ligne de commande utilisateur, ce qui n'est probablement pas la bonne chose à faire.
jw013
@ jw013 - Je ne savais pas que cela ne fonctionnait que pour les recherches d'alias, pas pour les fonctions. Merci pour l'information.
jordanm