O que você gostaria de fazer? Não execute rm
(1)? Execute-o com um argumento literal *
como em outras shells parecidas com Bourne (2)? Execute-o sem nenhum argumento (3)?
-
%código%. Ou
files=(*(N)); (($#files)) && rm -- $files
, mas isso também esconderia erros genuínos por (rm -- *) 2> /dev/null
, o que seria tolo. Você pode descartar o erro rm
, mas restaurar o stderr para o comando zsh
, embora com rm
-
%código%. Então, como em
(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
que emulate sh -c 'rm -- *' 2> /dev/null
agora emulado para aquela única linha de comando, o sh
não correspondente é passado como é para zsh
e *
reclama como se o arquivo rm
não existisse. Nós suprimimos o stderr de rm
como você faria em *
para suprimir essa mensagem de erro, mas novamente, isso é bobagem pois esconderia erros genuínos por rm
em oposição ao erro incorrido pelo mau comportamento de sh
passando um literal rm
para sh
. No entanto, *
não se queixaria de um arquivo rm
inexistente, portanto você poderia fazer rm -f '*'
-
%código%.
*
reclamaria quando não passasse nenhum argumento, embora, novamente, não emulate sh -c 'rm -f -- *'
: rm -- *(N)
.
Geralmente, rm
é o comando que você deseja usar se quiser que todos os arquivos desapareçam e só recebam um erro se os arquivos não puderem ser removidos ou se o IOW ainda estiver lá após rm -f
ter retornado. Você também geralmente deseja usar rm -f -- *(N)
em scripts para evitar que o usuário seja solicitado em algumas situações.
Aqui, chamar rm -f
quando o glob não combina está errado. O comportamento rm
1 está errado. É inofensivo para um padrão como -f
, mas para um como rm
, passar sh
como está quando não corresponde pode fazer com que o arquivo *
seja removido por engano:
$ ls
*.[ch] foo.txt
$ zsh -c 'rm *.[ch]'
zsh:1: no matches found: *.[ch]
$ ls
*.[ch] foo.txt
$ sh -c 'rm *.[ch]'
$ ls
foo.txt
A falha com um erro é a coisa mais sensata a fazer e é o que o *.[ch]
(e *.[ch]
, *.[ch]
, zsh
, fish
e o shell original do Unix) faz.
E se você quiser cuidar desse caso especial, csh
torna mais fácil o seu qualificador tcsh
glob (para noglob ) como no caso (1) acima. bash -o failglob
(pelo menos na versão recente ) torna isso ainda mais fácil, já que faz uma implícita < em> noglob para o comando zsh
. Então, o equivalente lá seria:
set files *
if count $files > /dev/null
rm -f -- $files
end
Veja Por que o nullglob não é o padrão para mais detalhes.
1 . Estritamente falando, é apenas (N)
desde o shell Bourne (desde o Unix V7 em 1979); versões anteriores de fish
(que chamaram set
sobre curingas não nomeadas, de onde vem o nome glob ) se comportaram como sh
ou sh
, ou seja, /etc/glob
iria abortar o comando se nenhum dos globs tivesse qualquer correspondência (e suprimiria os globs não correspondentes se pelo menos um deles tivesse alguma correspondência). O comportamento foi quebrado pela shell Bourne.