¿Qué le gustaría que hiciera en su lugar? ¿No se ejecuta rm
en absoluto (1)? ¿Ejecutarlo con un *
argumento literal como en otros shells tipo Bourne (2)? ¿Ejecutarlo sin ningún argumento (3)?
files=(*(N)); (($#files)) && rm -- $files
. O (rm -- *) 2> /dev/null
pero eso también ocultaría errores genuinos por los rm
cuales sería una tontería. Podrías descartar el zsh
error pero restaurar stderr para el rm
comando aunque con(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Luego, como en el sh
que zsh
ahora se emula para esa única línea de comando, la no coincidencia *
se pasa tal cual rm
y se rm
queja porque ese *
archivo no existe. Suprimimos rm
's stderr como lo haría en sh
suprimir ese mensaje de error, pero de nuevo, que es una tontería, ya que sería ocultar errores genuinos por rm
contraposición al error incurrido por el mal comportamiento de sh
pasar un literal *
a rm
. rm -f '*'
sin embargo, no se quejaría de un *
archivo no existente , por lo que podría haceremulate sh -c 'rm -f -- *'
rm -- *(N)
. rm
se queja de que cuando no se pasa ningún argumento, aunque, de nuevo, no rm -f
: rm -f -- *(N)
.
En general, rm -f
es el comando que desea usar si desea que se eliminen todos los archivos y solo obtiene un error si no se pueden eliminar los archivos o si IOW sigue ahí después de que rm
haya regresado. Por lo general, también desea usar -f
en scripts para evitar que se le solicite al usuario en algunas situaciones.
Aquí, llamar rm
cuando el globo no coincide está mal. El sh
1 comportamiento es incorrecto. Es inofensivo para un patrón como *
, pero para uno como *.[ch]
, pasar *.[ch]
como está cuando no coincide podría hacer que el *.[ch]
archivo se elimine por error:
$ 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
En su defecto con un error es lo más sensato que hacer y lo que es zsh
(y fish
, csh
,tcsh
, bash -o failglob
y la cáscara de Unix original) lo hace.
Y si desea cuidarse de ese caso especial, lo zsh
hace fácil con su (N)
calificador global (para noglob ) como en el caso (1) anterior. fish
(al menos en la versión reciente ) lo hace aún más fácil ya que hace un noglob implícito para el set
comando. Entonces, el equivalente allí sería:
set files *
if count $files > /dev/null
rm -f -- $files
end
Vea Por qué nullglob no es el predeterminado para más detalles.
1 . Estrictamente hablando, es solo sh
desde el shell Bourne (desde Unix V7 en 1979); las versiones anteriores de sh
(que llamaron /etc/glob
a comodines sin comillas, de donde proviene el nombre de glob ) se comportaron como csh
o zsh -o cshnullglob
, es decir /etc/glob
, abortarían el comando si ninguno de los globs coincidía (y suprimiría los globos no coincidentes si al menos uno de ellos tenía alguna coincidencia). El comportamiento fue roto por el shell Bourne.