Posso tornar 'rm' interativo somente ao usar globbing? (em bash ou zsh ou ambos)

15

Sempre que eu rm de vários itens ao mesmo tempo com shell globbing e há a menor possibilidade de que o padrão se expanda para mais do que eu esperava, sempre tento lembrar de adicionar -i , mas (é claro) poderia esquecer e acidentalmente apagar algo útil. Algumas pessoas tentam resolver este problema com um apelido, como alias rm='rm -i' mas eu odeio a idéia de tornar o rm sempre interativo, porque então eu vou usar o hábito de usar -f tempo, o que obviamente irá derrotar todo o propósito.

O que eu gostaria de fazer é fazer com que rm use somente -i quando eu uso o globbing e, para -f , é claro, substituir -i , então eu ainda posso apagar diretórios inteiros com o usual rm -rf junk .

Portanto, rm *blah* seria realmente rm -i *blah* , mas rm blah funcionaria exatamente como digitado.

No caso de haver uma diferença em como isso pode ser feito em diferentes shells, escolherei uma resposta que forneça métodos para bash e zsh sobre respostas que cobrem apenas uma ou outra.

Nota : não estou convencido de que isso seja necessariamente uma boa ideia; Só estou perguntando se é possível. Se você acha que esta é uma idéia estúpida, eu ficaria muito feliz em ouvir o raciocínio por trás de sua opinião, mas por favor, não poste tais comentários no campo de resposta . Respostas reais ou me dizem como fazer isso ou explicar isso / por que não é possível (ou possivelmente oferecer um método alternativo para obter um resultado similar). Mas se você quiser me dizer por que isso é burro, por favor poste como um comentário. Vou fazer comentários bem fundamentados, mesmo que discorde da conclusão.

    
por iconoclast 28.08.2012 / 19:25

2 respostas

9

Não é fácil. O problema é que quando você faz:

rm -- *.txt

O rm apenas vê a lista de arquivos, não o padrão globbing que já foi expandido pelo shell.

O que você poderia fazer é (zsh):

alias rm='noglob rm'

Isso diz ao zsh que os padrões não devem ser expandidos ao chamar rm. Então você pode redefinir rm como uma função que faz a própria expansão e adiciona o "-i" se precisar ser algo como:

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

O problema com essa abordagem é que esse novo "rm" não vê a diferença entre

rm *

e

rm '*'

Para remover o arquivo chamado * , você teria que escrevê-lo:

rm [*]
    
por 28.08.2012 / 22:30
-1

Funciona no bash, provavelmente em outros shells. Coloque no seu .bashrc

function rm() { 
  while test "${1:0:1}" = "-"; do 
    shift
  done
  if test $# -eq 1; then 
    command rm "$1"
  else 
    command rm -i "$@"
  fi
}
    
por 28.08.2012 / 20:37