Ninguna de las respuestas publicadas el 2018-06-01, con la excepción de la línea de comando única publicada por foxidrive , realmente eliminó todos los archivos y todas las carpetas / directorios %PathToFolder%
. Esa es la razón para publicar una respuesta más con una línea de comando única muy simple para eliminar todos los archivos y subcarpetas de una carpeta, así como un archivo por lotes con una solución más compleja que explica por qué todas las otras respuestas publicadas en 2018-06-01 usando DEL y FOR con RD no pudo limpiar una carpeta por completo.
La solución de línea de comando simple simple que, por supuesto, también se puede usar en un archivo por lotes:
pushd "%PathToFolder%" 2>nul && ( rd /Q /S "%PathToFolder%" 2>nul & popd )
Esta línea de comando contiene tres comandos ejecutados uno después del otro.
El primer comando PUSHD empuja la ruta del directorio actual en la pila y luego crea%PathToFolder%
el directorio actual para ejecutar el proceso del comando.
Esto también funciona para las rutas UNC de forma predeterminada debido a que las extensiones de comando están habilitadas de forma predeterminada y en este caso PUSHD crea una letra de unidad temporal que apunta a ese recurso de red especificado y luego cambia la unidad y el directorio actuales, utilizando la letra de unidad recién definida.
PUSHD emite el siguiente mensaje de error para manejar STDERR si el directorio especificado no existe en absoluto:
El sistema no puede encontrar la ruta especificada.
Este mensaje de error se suprime al redirigirlo 2>nul
al dispositivo NUL .
El siguiente comando RD se ejecuta solo si el cambio del directorio actual para el proceso de comando actual al directorio especificado fue exitoso, es decir, el directorio especificado existe.
El comando RD con las opciones /Q
y /S
elimina un directorio silenciosamente con todos los subdirectorios incluso si el directorio especificado contiene archivos o carpetas con atributos ocultos o con un conjunto de atributos de solo lectura. El atributo del sistema nunca impide la eliminación de un archivo o carpeta.
No eliminados son:
Carpetas utilizadas como el directorio actual para cualquier proceso en ejecución. No se puede eliminar todo el árbol de carpetas de dicha carpeta si se usa una carpeta como el directorio actual para cualquier proceso en ejecución.
Los archivos abiertos actualmente por cualquier proceso en ejecución con permisos de acceso a archivos establecidos en el archivo abierto para evitar la eliminación del archivo mientras está abierto por la aplicación / proceso en ejecución. Tal archivo abierto evita también la eliminación de todo el árbol de carpetas al archivo abierto.
Archivos / carpetas en los que el usuario actual no tiene los permisos requeridos (NTFS) para eliminar el archivo / carpeta, lo que impide también la eliminación del árbol de carpetas a este archivo / carpeta.
Esta línea de comando utiliza la primera razón para no eliminar una carpeta para eliminar todos los archivos y subcarpetas de la carpeta especificada, pero no la carpeta en sí. La carpeta se convierte temporalmente en el directorio actual para ejecutar el proceso de comando que impide la eliminación de la carpeta en sí. Por supuesto, esto da como resultado la salida de un mensaje de error mediante el comando RD :
El proceso no puede acceder al archivo porque está siendo utilizado por otro proceso.
Archivo es el término incorrecto aquí, ya que en realidad la carpeta está siendo utilizada por otro proceso, el proceso de comando actual que ejecutó el comando RD . Bueno, en realidad una carpeta es para el sistema de archivos un archivo especial con un directorio de atributos de archivo que explica este mensaje de error. Pero no quiero profundizar demasiado en la gestión del sistema de archivos.
Este mensaje de error, como todos los demás mensajes de error, que podría ocurrir debido a las tres razones escritas anteriormente, se suprime al redirigirlo 2>nul
desde el controlador STDERR al dispositivo NUL .
El tercer comando, POPD , se ejecuta independientemente del valor de salida del comando RD .
POPD abre la ruta del directorio empujada por PUSHD desde la pila y cambia el directorio actual para ejecutar el proceso de comando a este directorio, es decir, restaura el directorio actual inicial. POPD elimina la letra de unidad temporal creada por PUSHD en caso de una ruta de carpeta UNC.
Nota: POPD puede fallar silenciosamente al restaurar el directorio actual inicial en caso de que el directorio actual inicial fuera un subdirectorio del directorio para limpiar que ya no existe. En este caso especial %PathToFolder%
permanece el directorio actual. Por lo tanto, es recomendable ejecutar la línea de comando anterior no desde un subdirectorio de %PathToFolder%
.
Un hecho más interesante :
probé la línea de comando también usando una ruta UNC al compartir el directorio local C:\Temp
con el nombre compartido Temp
y usando la ruta UNC \\%COMPUTERNAME%\Temp\CleanTest
asignada a la variable de entorno PathToFolder
en Windows 7. Si el directorio actual al ejecutar la línea de comando es un subdirectorio de un local compartido La carpeta a la que se accede mediante la ruta UNC, es decir C:\Temp\CleanTest\Subfolder1
, Subfolder1
es eliminada por RD , y el siguiente POPD falla silenciosamente al C:\Temp\CleanTest\Subfolder1
volver a crear el directorio actual, lo que resulta en Z:\CleanTest
el directorio actual para el proceso de comando en ejecución. Entonces, en este caso muy especial, la letra de unidad temporal permanece hasta que se cambie el directorio actual, por ejemplo concd /D %SystemRoot%
a un directorio local realmente existente. Desafortunadamente POPDno sale con un valor mayor de 0 si no puede restaurar el directorio actual inicial, lo que hace imposible detectar esta condición de error muy especial usando solo el código de salida de POPD . Sin embargo, se puede suponer que nadie se encuentra con este caso de error muy especial ya que las rutas UNC generalmente no se utilizan para acceder a archivos y carpetas locales.
Para comprender aún mejor los comandos utilizados, abra una ventana de símbolo del sistema, ejecute allí los siguientes comandos y lea la ayuda que se muestra para cada comando con mucho cuidado.
Una sola línea con múltiples comandos usando el archivo por lotes de Windows explica los operadores &&
y se &
usa aquí.
A continuación, veamos la solución de archivo por lotes utilizando el comando DEL para eliminar archivos %PathToFolder%
y FOR y RD para eliminar las subcarpetas %PathToFolder%
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Clean the folder for temporary files if environment variable
rem PathToFolder is not defined already outside this batch file.
if not defined PathToFolder set "PathToFolder=%TEMP%"
rem Remove all double quotes from folder path.
set "PathToFolder=%PathToFolder:"=%"
rem Consisted the folder path only of double quotes?
if not defined PathToFolder goto EndCleanFolder
rem Remove a backslash at end of folder path.
if "%PathToFolder:~-1%" == "\" set "PathToFolder=%PathToFolder:~0,-1%"
rem Consisted folder path only of a backslash (with one or more double quotes)?
if not defined PathToFolder goto EndCleanFolder
rem Delete all files in specified folder including files with hidden
rem or read-only attribute set, except the files currently opened by
rem a running process which prevents deletion of the file while being
rem opened by the application, or on which the current user has not
rem the required permissions to delete the file.
del /A /F /Q "%PathToFolder%\*" >nul 2>nul
rem Delete all subfolders in specified folder including those with hidden
rem attribute set recursive with all files and subfolders, except folders
rem being the current directory of any running process which prevents the
rem deletion of the folder and all folders above, folders containing a file
rem opened by the application which prevents deletion of the file and the
rem entire folder structure to this file, or on which the current user has
rem not the required permissions to delete a folder or file in folder tree
rem to delete.
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul
:EndCleanFolder
endlocal
El archivo por lotes primero se asegura de que la variable de entorno PathToFolder
esté realmente definida con una ruta de carpeta sin comillas dobles y sin una barra diagonal inversa al final. La barra diagonal inversa al final no sería un problema, pero las comillas dobles en una ruta de carpeta podrían ser problemáticas debido a que el valor de PathToFolder
se concatena con otras cadenas durante la ejecución del archivo por lotes.
Importantes son las dos líneas:
del /A /F /Q "%PathToFolder%\*" >nul 2>nul
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul
El comando DEL se usa para eliminar todos los archivos en el directorio especificado.
- La opción
/A
es necesaria para procesar realmente todos los archivos, incluidos los archivos con el atributo oculto que DEL ignoraría sin usar la opción /A
.
- La opción
/F
es necesaria para forzar la eliminación de archivos con el conjunto de atributos de solo lectura.
- La opción
/Q
es necesaria para ejecutar una eliminación silenciosa de varios archivos sin preguntar al usuario si realmente se deben eliminar varios archivos.
>nul
es necesario para redirigir la salida de los nombres de archivo escritos para manejar STDOUT al dispositivo NUL del cual no se puede eliminar debido a que un archivo está abierto actualmente o el usuario no tiene permiso para eliminar el archivo.
2>nul
es necesario redirigir la salida del mensaje de error para cada archivo que no se puede eliminar del identificador STDERR al dispositivo NUL .
Los comandos FOR y RD se utilizan para eliminar todos los subdirectorios en el directorio especificado. Pero for /D
no se usa porque FOR ignora en este caso los subdirectorios con el conjunto de atributos ocultos. Por esa razón, for /F
se utiliza para ejecutar la siguiente línea de comando en un proceso de comando separado que se inicia en segundo plano con %ComSpec% /c
:
dir "%PathToFolder%\*" /AD /B 2>nul
Las salidas DIR en formato simple debido a /B
las entradas de directorio con atributo D
, es decir, los nombres de todos los subdirectorios en el directorio especificado independientemente de otros atributos como el atributo oculto sin una ruta. 2>nul
se utiliza para redirigir la salida del mensaje de error por DIR en ningún directorio encontrado del identificador STDERR al dispositivo NUL .
El operador de redirección >
debe escapar con el carácter de intercalación ^
, en la línea de comando FOR para ser interpretado como un carácter literal cuando el intérprete de comandos de Windows procesa esta línea de comando antes de ejecutar el comando FOR que ejecuta la dir
línea de comando incrustada en un proceso de comando separado iniciado en el fondo.
FOR procesa la salida capturada escrita para manejar STDOUT de un proceso de comando iniciado que son los nombres de los subdirectorios sin ruta y nunca encerrados entre comillas dobles.
FOR con opción /F
ignora las líneas vacías que no aparecen aquí ya que DIR con opción /B
no genera líneas vacías.
FOR también ignoraría las líneas que comienzan con un punto y coma, que es el carácter predeterminado de final de línea. Un nombre de directorio puede comenzar con un punto y coma. Por esa razón, eol=|
se utiliza para definir el carácter de barra vertical como el carácter de fin de línea que ningún directorio o archivo puede tener en su nombre.
FOR dividiría la línea en subcadenas usando espacio y tabulación horizontal como delimitadores y asignaría solo la primera cadena delimitada por espacio / tabulación a la variable de bucle especificada I
. Aquí no se desea este comportamiento de división debido a que un nombre de directorio puede contener uno o más espacios. Por delims=
lo tanto, se utiliza para definir una lista vacía de delimitadores para deshabilitar el comportamiento de división de línea y asignarse a la variable de bucle I
, siempre el nombre completo del directorio.
El comando FOR ejecuta el comando RD para cada nombre de directorio sin una ruta, razón por la cual en la línea de comando RD la ruta de la carpeta debe especificarse una vez más, que se concatena con el nombre de la subcarpeta.
Para comprender los comandos utilizados y cómo funcionan, abra una ventana de símbolo del sistema, ejecute allí los siguientes comandos y lea con cuidado todas las páginas de ayuda que se muestran para cada comando.
del /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rd /?
rem /?
set /?
setlocal /?