Para fines de prueba, creé los siguientes directorios.
user@linux:~$ mkdir dir0{1..3}
user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei 31 10:45 dir01
drwxr-xr-x 2 user user 4.0K Mei 31 10:45 dir02
drwxr-xr-x 2 user user 4.0K Mei 31 10:45 dir03
user@linux:~$
Luego lo quité confind -exec
user@linux:~$ find -type d -exec rmdir {} \;
rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory
find: ‘./dir01’: No such file or directory
find: ‘./dir03’: No such file or directory
user@linux:~$
Los directorios fueron eliminados, lo verifiqué.
user@linux:~$ ls -l
total 0
user@linux:~$
Mis preguntas son:
1) No entiendo por qué estaban ahí los mensajes. ¿Alguna idea de por qué?
rmdir: failed to remove '.': Invalid argument
find: ‘./dir02’: No such file or directory
No veo este tipo de error conrmdir
user@linux:~$ mkdir dir0{1..3}
user@linux:~$
user@linux:~$ ls -l
total 12K
drwxr-xr-x 2 user user 4.0K Mei 31 22:58 dir01
drwxr-xr-x 2 user user 4.0K Mei 31 22:58 dir02
drwxr-xr-x 2 user user 4.0K Mei 31 22:58 dir03
user@linux:~$
user@linux:~$ rmdir *
user@linux:~$
user@linux:~$ ls -l
total 0
user@linux:~$
2) ¿Es posible eliminar estos mensajes?
Respuesta1
Obtiene esos errores de "No existe tal archivo o directorio" find
porque find
está intentando ingresar a directorios que acaba de eliminar. De forma predeterminada, aplicará sus acciones a todos los elementos coincidentes en el directorio que está visitando actualmente antes de continuar con los subdirectorios.
Agregue -depth
a la invocación de find
para realizar find
una búsqueda profunda de sus rutas de búsqueda, lo que a su vez significa que si ejecuta rmdir
en un directorio, ya lo habrá visitado y no intentará visitarlo nuevamente.
La -depth
opción está implícita cuando se usa -delete
por este motivo (en implementaciones de find
that has -delete
).
find . -depth -type d -exec rmdir {} \;
-depth
es una opción estándar para la find
utilidad.
Tenga en cuenta que rmdir
sólo funciona en directorios vacíos. Si tiene muchos directorios que no están vacíos, el comando anterior generará muchos mensajes de error.
En su lugar, si find
lo admite, utilice -empty
:
find . -type d -empty -delete
Esto eliminaría directorios vacíos.
Con un find
que no tiene el no estándar -delete
ni -emtpy
:
find . -depth -type d -exec sh -c '
for dirpath do
set -- "$dirpath"/*
[ ! -e "$1" ] && rmdir "$dirpath"
done' sh {} +
Esto probaría si los directorios encontrados estaban vacíos y, si lo estuvieran, se eliminarían.
Es un código largo para evitar ver algunos mensajes de error debido a que los directorios no están vacíos, pero cualquier mensaje de error quesonEs de esperar que los archivos producidos sean más interesantes de observar, ya que probablemente sean errores de "permiso denegado". Redirigir los errores al /dev/null
primer find
comando en la parte superior habría ocultado dichos errores.
Respuesta2
Lo que presumiblemente sucede es que, con la -exec ... \;
construcción, find hace su trabajo paso a paso:
- recorrer el árbol de directorios, encontrar entradas que coincidan
-type d
y - ejecute
rmdir
dichas entradas tan pronto como las encuentre.
Esto significa que, en su ejemplo, find buscará en dir01
, lo tendrá en cuenta como un directorio para ingresar más tarde, luego rmdir
lo ejecutará y luego, al intentar recurrir a dir01
, fallará porque ya no existe.
Ejecutar with -exec rmdir {} +
debería ayudar en este caso: rmdir dir01 dir02 dir03
se emitirá una única llamada a. Esto elimina los últimos tres mensajes de error.
El mensaje de error se debe .
a que, bueno .
, el directorio actual es de hecho un directorio, pero no uno que rmdir
se pueda eliminar, porque no está vacío. Utilízalo -min-depth
para dejar de considerarlo, haciendo el comando:
find -mindepth 1 -type d -exec rmdir {} +
Esto no es perfecto; Los directorios anidados o una gran cantidad de directorios coincidentes aún podrían causar que se impriman mensajes de error, pero esto debería funcionar en el caso simple de la pregunta.