O que você gostaria que ele fizesse? Não é executado rm
(1)? Executá-lo com um *
argumento literal como em outros shells Bourne (2)? Executá-lo sem nenhum argumento (3)?
files=(*(N)); (($#files)) && rm -- $files
. Ou (rm -- *) 2> /dev/null
mas isso também ocultaria erros genuínos pelos rm
quais seria tolo. Você pode descartar o zsh
erro, mas restaurar o stderr para o rm
comando, embora com(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Então, como no sh
qual zsh
agora emulado para essa linha de comando única, a não correspondência *
é passada como está rm
e rm
reclama, pois esse *
arquivo não existe. Nós suprimimos rm
o stderr como você faria sh
para suprimir essa mensagem de erro, mas, novamente, isso é bobagem, pois ocultaria erros genuínos por rm
oposição ao erro incorrido pelo mau comportamento de sh
passar um literal *
para rm
. rm -f '*'
não iria reclamar de um *
arquivo inexistente , então você poderia fazeremulate sh -c 'rm -f -- *'
rm -- *(N)
. rm
reclamaria quando não fosse aprovado em nenhum argumento, porém novamente rm -f
: não rm -f -- *(N)
.
Geralmente, rm -f
é o comando que você deseja usar se você deseja que todos os arquivos sejam removidos e só recebe um erro se os arquivos não puderem ser removidos ou o IOW ainda estiver lá após o rm
retorno. Você também geralmente deseja usar -f
scripts para evitar que o usuário seja solicitado em algumas situações.
Aqui, telefonar rm
quando o globo não corresponde está errado. O comportamento sh
1 está errado. É inofensivo para um padrão como *
, mas para um exemplo *.[ch]
, passar *.[ch]
como está quando não corresponde pode causar a *.[ch]
remoção do arquivo 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
Falhando com um erro é a coisa mais sensata a fazer e é o que zsh
(e fish
, csh
, tcsh
, bash -o failglob
e o shell do Unix original) faz.
E se você quiser cuidar desse caso especial, zsh
facilite com o (N)
qualificador glob (para noglob ) como no caso (1) acima. fish
(pelo menos na versão recente ) facilita ainda mais, como faz um noglob implícito para o set
comando. Então, o equivalente lá seria:
set files *
if count $files > /dev/null
rm -f -- $files
end
Consulte Por que o nullglob não é o padrão para obter mais detalhes.
1 . A rigor, é apenas sh
desde o shell Bourne (desde o Unix V7 em 1979); as versões anteriores sh
(que chamavam /etc/glob
curingas não citados, de onde vem o nome do globo ) se comportavam como csh
ou zsh -o cshnullglob
, isto é /etc/glob
, interromperiam o comando se nenhum dos globs tivesse correspondência (e suprimiria os globs não correspondentes, se pelo menos um deles teve qualquer correspondência). O comportamento foi quebrado pelo shell Bourne.