¿Estás tratando de eliminar todo en el directorio actual? ¿Cuál es el directorio actual?
cutrightjm
Podrías usar setopt extended_glob(o incluso simple rm * >/dev/null 2>&1) pero realmente deberías hacer una solución alternativa para no necesitar rm *, eso es absolutamente peligroso
grochmal
Realmente deberías hundirte en /dev/nulllugar de eso dev/zero. Además, a su redirección stderr le falta un &; debería ser 2>&1.
roaima
El mensaje de error se genera zshdurante la evaluación del comando y no durante el tiempo de ejecución del comando en sí (debido al error, el comando ni siquiera se ejecuta). Las redirecciones de salida aquí solo afectarían la salida del comando y no el shell en sí.
Adaephon
Respuestas:
42
Este comportamiento es controlado por Zsh nomatch opción . Por defecto, si una línea de comando contiene una expresión global que no coincide con nada, Zsh imprimirá el mensaje de error que está viendo y no ejecutará el comando en absoluto. Puede deshabilitar esto ejecutando
setopt +o nomatch
Luego, las expresiones globales que no coinciden con nada se dejarán tal cual, y recibirá un mensaje de error rm(que puede desactivar usando -f, aunque es una mala idea, ya que forzará las eliminaciones en otras situaciones en las que no querer).
El comportamiento también está controlado por las opciones nullgloby cshnullglob. Si nullglobse establece y no se encuentra ningún archivo coincidente, el patrón se elimina de la lista de argumentos en lugar de generar un error. La configuración cshnullglobtiene un efecto similar a menos que todos los patrones en un comando no coincidan, en cuyo caso se informará un error. Nota: configuración nullglobo cshnullglobanulaciones nomatch. También puede establecer nullgloblos patrones individuales utilizando el calificador pegote N: rm *(N).
Adaephon
nomatches menos que ideal, eso es lo que hacen los proyectiles tipo Bourne. Si el patrón no coincide, se pasa como está a rm(!), Lo que rmgenerará un error, o peor aún, podría eliminar el archivo incorrecto para un patrón como, *.[ch]por ejemplo.
Stéphane Chazelas
9
¿Qué le gustaría que hiciera en su lugar? ¿No se ejecuta rmen 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/nullpero eso también ocultaría errores genuinos por los rmcuales sería una tontería. Podrías descartar el zsherror pero restaurar stderr para el rmcomando aunque con(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null. Luego, como en el shque zshahora se emula para esa única línea de comando, la no coincidencia *se pasa tal cual rmy se rmqueja porque ese *archivo no existe. Suprimimos rm's stderr como lo haría en shsuprimir ese mensaje de error, pero de nuevo, que es una tontería, ya que sería ocultar errores genuinos por rmcontraposición al error incurrido por el mal comportamiento de shpasar 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). rmse queja de que cuando no se pasa ningún argumento, aunque, de nuevo, no rm -f: rm -f -- *(N).
En general, rm -fes 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 rmhaya regresado. Por lo general, también desea usar -fen scripts para evitar que se le solicite al usuario en algunas situaciones.
Aquí, llamar rmcuando el globo no coincide está mal. El sh1 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 failgloby la cáscara de Unix original) lo hace.
Y si desea cuidarse de ese caso especial, lo zshhace 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 setcomando. Entonces, el equivalente allí sería:
set files *if count $files >/dev/null
rm -f -- $files
end
1 . Estrictamente hablando, es solo shdesde el shell Bourne (desde Unix V7 en 1979); las versiones anteriores de sh(que llamaron /etc/globa comodines sin comillas, de donde proviene el nombre de glob ) se comportaron como csho 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.
Creo que espera recibir el mensaje de error rmy no del shell. Algo así como "rm: no se puede eliminar` * ': No existe tal archivo o directorio ".
Emmanuel
@ Emmanuel, entonces eso es 2: emulate sh -c 'rm -- *'obtener el comportamiento (buggy IMO) del shell Bourne.
Stéphane Chazelas
@Stephane_Chazelas como está escrito, 2 es la respuesta correcta a una pregunta que no hizo :).
Emmanuel
@Emmanuel, los 3 responden la pregunta: cómo deshacerse del error "Sin coincidencia". El código del OP suprime los rmerrores. Eso es algo que haría en otros shells para suprimir el error cuando no hay un archivo coincidente y eso también provoca la supresión de errores rm genuinos. Mi respuesta describe eso y espero que muestre cómo es preferible el comportamiento zsh.
setopt extended_glob
(o incluso simplerm * >/dev/null 2>&1
) pero realmente deberías hacer una solución alternativa para no necesitarrm *
, eso es absolutamente peligroso/dev/null
lugar de esodev/zero
. Además, a su redirección stderr le falta un&
; debería ser2>&1
.zsh
durante la evaluación del comando y no durante el tiempo de ejecución del comando en sí (debido al error, el comando ni siquiera se ejecuta). Las redirecciones de salida aquí solo afectarían la salida del comando y no el shell en sí.Respuestas:
Este comportamiento es controlado por Zsh
nomatch
opción . Por defecto, si una línea de comando contiene una expresión global que no coincide con nada, Zsh imprimirá el mensaje de error que está viendo y no ejecutará el comando en absoluto. Puede deshabilitar esto ejecutandoLuego, las expresiones globales que no coinciden con nada se dejarán tal cual, y recibirá un mensaje de error
rm
(que puede desactivar usando-f
, aunque es una mala idea, ya que forzará las eliminaciones en otras situaciones en las que no querer).fuente
nullglob
ycshnullglob
. Sinullglob
se establece y no se encuentra ningún archivo coincidente, el patrón se elimina de la lista de argumentos en lugar de generar un error. La configuracióncshnullglob
tiene un efecto similar a menos que todos los patrones en un comando no coincidan, en cuyo caso se informará un error. Nota: configuraciónnullglob
ocshnullglob
anulacionesnomatch
. También puede establecernullglob
los patrones individuales utilizando el calificador pegoteN
:rm *(N)
.nomatch
es menos que ideal, eso es lo que hacen los proyectiles tipo Bourne. Si el patrón no coincide, se pasa como está arm
(!), Lo querm
generará un error, o peor aún, podría eliminar el archivo incorrecto para un patrón como,*.[ch]
por ejemplo.¿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 losrm
cuales sería una tontería. Podrías descartar elzsh
error pero restaurar stderr para elrm
comando aunque con(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Luego, como en elsh
quezsh
ahora se emula para esa única línea de comando, la no coincidencia*
se pasa tal cualrm
y serm
queja porque ese*
archivo no existe. Suprimimosrm
's stderr como lo haría ensh
suprimir ese mensaje de error, pero de nuevo, que es una tontería, ya que sería ocultar errores genuinos porrm
contraposición al error incurrido por el mal comportamiento desh
pasar un literal*
arm
.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, norm -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 querm
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. Elsh
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:En su defecto con un error es lo más sensato que hacer y lo que es
zsh
(yfish
,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 elset
comando. Entonces, el equivalente allí sería: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 desh
(que llamaron/etc/glob
a comodines sin comillas, de donde proviene el nombre de glob ) se comportaron comocsh
ozsh -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.fuente
rm
y no del shell. Algo así como "rm: no se puede eliminar` * ': No existe tal archivo o directorio ".emulate sh -c 'rm -- *'
obtener el comportamiento (buggy IMO) del shell Bourne.rm
errores. Eso es algo que haría en otros shells para suprimir el error cuando no hay un archivo coincidente y eso también provoca la supresión de errores rm genuinos. Mi respuesta describe eso y espero que muestre cómo es preferible el comportamiento zsh.