¿Puedo hacer que `rm` sea interactivo solo cuando uso globbing? (en bash o zsh o en ambos)

15

Cada vez que rmmultiplico varios elementos a la vez con un globo de caparazón e incluso existe la más mínima posibilidad de que el patrón se expanda más de lo que esperaba, siempre trato de recordar agregar -i, pero (por supuesto) podría olvidar y eliminar accidentalmente algo útil. Algunas personas intentan resolver este problema con un alias, como, alias rm='rm -i'pero odio la idea de hacer que rm sea siempre interactivo, porque entonces tendré el hábito de usarlo -ftodo el tiempo, lo que obviamente anulará todo el propósito.

Lo que me gustaría hacer es rmusarlo solo -icuando uso globbing y, por -fsupuesto -i, anularlo , por lo que aún puedo volar directorios completos con lo habitual rm -rf junk.

Por rm *blah*lo tanto , realmente sería, rm -i *blah*pero rm blahfuncionaría exactamente como se escribió.

En caso de que haya una diferencia en cómo se puede lograr esto en diferentes shells, elegiré una respuesta que proporcione métodos para bash y zsh en lugar de respuestas que solo cubran una u otra.


Nota : en realidad no estoy convencido de que esto sea necesariamente una buena idea; Solo estoy preguntando si es posible. Si cree que esta es una idea estúpida, me alegraría escuchar el razonamiento detrás de su opinión, pero no publique tales comentarios en el campo de respuesta . Las respuestas reales me dicen cómo hacer esto o me explican por qué no es posible (o posiblemente ofrecen un método alternativo para obtener un resultado similar). Pero si quieres decirme por qué esto es tonto, publícalo como comentario. Votaré los comentarios bien razonados incluso si no estoy de acuerdo con la conclusión.

iconoclasta
fuente
77
Algunas sugerencias: con las utilidades GNU, rm -Ies así -ique solo se activa cuando -rse pasan más de tres archivos o se pasa. En bash, use el Ctrl-x *atajo de teclado para expandir el globo e inspeccionarlo usted mismo.
jw013
2
Con bash, creo que la respuesta es "no". Con zsh, puede aprovecharlo noglob, p. Ej., Alias ​​rm to noglob my-rm, y luego hacer que my-rm sea un script que compruebe si hay un globo, lo expande y pasa -i o no. No estoy seguro, no sé zsh.
derobert
@derobert: ciertamente suena como usted sabe zsh bastante bien.
iconoclasta
@iconoclast No, no zsh, solo Google. Curiosamente, lo encontré al intentar encontrar cómo hacerlo en bash. :-P
Derobert
Si desea algo que se parezca a rm pero que en realidad funcione de manera diferente, debería escribir un script (o alias / function / function key) llamado myrmy dejar que ese script haga las cosas maravillosas que le gustan.
Walter A

Respuestas:

9

No es fácil. El problema es que cuando haces:

rm -- *.txt

rm solo ve la lista de archivos, no el patrón global que ya ha sido expandido por el shell.

Lo que puedes hacer es (zsh):

alias rm='noglob rm'

Esto le dice a zsh que los patrones no deben expandirse al llamar a rm. Luego puede redefinir rm como una función que realiza la expansión en sí misma y agrega "-i" si es necesario, como:

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

Sin embargo, el problema con ese enfoque es que este nuevo "rm" no ve la diferencia entre

rm *

y

rm '*'

Para eliminar el archivo llamado *, deberías escribirlo:

rm [*]
Stéphane Chazelas
fuente
-1

Funciona en bash, probablemente en otros proyectiles. Coloque en su.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
fuente
3
Puede usar command rmpara evitar la codificación rígida PATH. Además, el enfoque de verificar el recuento de argumentos es poco confiable, ya que rmpuede tomar opciones.
jw013
1
Se debe citar el "$ 1", o esto fallará si el único archivo aprobado contiene un espacio. @ jw013 - También puede escapar del comando, por ejemplo\rm
jordanm
@jordanm Tiene razón sobre la necesidad de citar $1con comillas dobles, pero está equivocado acerca del escape del comando. Las citas solo suprimen los alias, NO la función de búsqueda. Esta respuesta sugiere una función, no un alias.
jw013
1
Al menos la edición anterior era funcional: la nueva edición descarta las opciones de la línea de comandos del usuario, lo que probablemente no sea lo correcto.
jw013
@ jw013: no sabía que solo funcionaba para búsquedas de alias, no para funciones. Gracias por la información.
jordanm