2009-02-18 13 views
9

Nous avons un script de traitement par lots qui supprime les fichiers (del) et les répertoires (rd). Est-ce que quelqu'un sait comment stopper (échouer) l'exécution du script si l'une de ces instructions de suppression échoue? Ils pourraient échouer si un fichier/répertoire est verrouillé par Windows. Merci.Comment faire pour arrêter le script batch sur l'échec

Mise à jour

déclarations que je utilise:

Del: del *.* /S /Q

RD: FOR /D %%G in (*) DO RD /s /q %%G

Répondre

12

Pour supprimer le fichier s, vous pouvez d'abord essayer de ren (renommer) le fichier. ren affectera ERRORLEVEL à 1 si le fichier est verrouillé. Ajouter des citations autour du nom de fichier

@echo OFF 

:: Delete all files, but exit if a file is locked. 
for %%F in (*.*) do (
    @echo Deleting %%F 
    ren "%%F" tmp 2> nul 
    if ERRORLEVEL 1 (
     @echo Cannot delete %%F, it is locked. 
     exit /b 1 
    ) 
    del tmp 
) 

Je soupçonne que vous pourrez peut-être faire la même chose pour les répertoires, mais je ne peux pas sembler comprendre comment obtenir un répertoire fermai je peux tester. Ce qui suit peut fonctionner:

:: Remove all directories, but exit if one is locked. 
FOR /D %%G in (*) DO (
    @echo Removing %%G 
    ren "%%G" tmpdir 2> nul 
    if ERRORLEVEL 1 (
     @echo Cannot remove %%G, it is locked 
     exit /b 1 
    ) 
    RD /s /q tmpdir 
) 
+1

Cela ne fonctionne pas pour l'exécution du fichier image de processus. Lorsque vous démarrez 'notepad.exe', vous pouvez le renommer, mais vous ne pouvez pas supprimer son fichier image. Idem pour les DLL chargées. – wqw

+1

Vous pouvez obtenir un répertoire verrouillé en ouvrant une fenêtre cmd à l'intérieur ... –

3

EDIT: droit, si del ne définit pas correctement la ERRORLEVEL. Voir ERRORLEVEL on DEL et Windows delete command can fail silently

PRÉCÉDENT (incorrect) SOLUTION

Vous devriez vérifier la errorlevel.

Par exemple:

del file.txt 
if errorlevel 1 goto FAIL 
:PASS 
echo Worked! 
goto :END 

:FAIL 
echo Failed! 
exit /B 1 

:END 
+0

ne semble pas fonctionner: C: \> test.bat C: \> del boo.doc boo.doc. Le processus ne peut pas accéder au fichier car il est utilisé par un autre processus. C: \> if errorlevel 1 goto ÉCHEC C: \> echo Travaillé! A travaillé! Echec de C: \> echo! Échec! C: \> exit/B 1 –

6

DEL ne retourne pas errorlevel si le fichier est verrouillé. Je viens de faire un test avec un fichier Excel et j'ai vu un zéro (sur Windows XP).

Il peut être préférable d'utiliser IF EXIST pour le fichier à supprimer après la suppression.

del file.txt 
if exist file.txt ECHO "FAIL" 

APRÈS EDIT Avertissement: Je ne sais pas comment cela ... exécute

Vous pouvez le faire pour les fichiers

DIR /B /S /A-d > c:\filestodelete.txt 

del *.* /S /Q  

FOR /F %%i in (c:\filestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS 
) 

puis pour les répertoires

DIR /B /S /Ad > c:\directoriestodelete.txt 

FOR /D %%G in (*) DO RD /s /q %%G  

FOR /F %%i in (c:\directoriestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS 
) 
+0

Bonne suggestion - sauf que je supprime plusieurs fichiers (voir la publication éditée), donc il est difficile de faire l'instruction exist pour chaque répertoire/fichier. –

+0

@Marcus Leon - Je pense que ce que j'ai ajouté devrait fonctionner pour votre cas général ... –

1

Voici ma méthode préférée pour vérifier les erreurs lors de la suppression de fichiers. Nous redirigeons la "sortie d'erreur" (fichier standard "2") vers un fichier (par exemple delCmd.err). Ensuite, nous utilisons la commande FOR pour accéder à l'opérateur de taille de fichier "z". Si la taille du fichier de sortie n'est pas 0, alors nous savons que "del" a une erreur ... nous affichons l'erreur avec la commande "type" et quittons le fichier batch avec un code d'erreur non nul:

del unwanted.txt 2> delCmd.err 
FOR /F "usebackq" %%A IN ('delCmd.err') DO set size=%%~zA 
if not "%size%"=="0" (
    echo Error deleting unwanted.txt 
    type delCmd.err 
    exit /B 1 
) 
+0

+1, Doh! Si simple! – dbenham

1

Voici une version plus courte de la variante de surveillance des résultats.Ceci utilise 2>&1 astuce pour rediriger stderr vers stdout et for /f pour vérifier toute sortie.

@echo off 
setlocal 
set error=0 
for /f %%i in ('del notepad2.exe 2^>^&1') do set error=1 
echo %error% 
0

Il existe un script qui fonctionnera comme un charme. Il teste l'échec de la suppression en testant l'existence du fichier/répertoire supposé supprimé.

La sortie sera un répertoire c: \ mydirectory avec un contenu complètement vide. Toute erreur interrompt le processus et est signalée. Le seul inconvénient est que les répertoires sont supprimés récursivement, car il n'y a pas de moyen simple de commencer à supprimer des répertoires en commençant par les répertoires les plus "sub".

@echo OFF 
set path_to_clean=c:\mydirectory 

@echo -Deleting Files 
dir /A-D /S /B %path_to_clean%\* > fileslist.txt 
for /F %%F in (fileslist.txt) do (
    @echo Deleting %%F 
    del %%F 2> nul 
    if exist %%F (
     @echo Cannot delete %%F, it is locked. 
     goto errorhandling 
    ) 
) 
del fileslist.txt 
@echo -Deleting Files done 

@echo -Deleting Directories 
dir /AD /B %path_to_clean%\* > directorieslist.txt 

for /F %%D in (directorieslist.txt) do (
    @echo Deleting %path_to_clean%\%%D 
    rmdir /S /Q %path_to_clean%\%%D 2> nul 
    if exist %path_to_clean%\%%D (
     @echo Cannot delete %path_to_clean%\%%D. This folder or one of its sub-directories is locked. 
     goto errorhandling 
    ) 
) 
del directorieslist.txt 
@echo -Deleting Directories done 

:errorhandling 
rem some code here 
-1

Pour rd et rmdir vous pouvez faire

rd "some directory" || rem 

cela définir correctement errorlevel - see

+0

Malheureusement cette astuce ne fonctionne pas avec la commande DEL :-( – dbenham

+1

aussi rd ne définit pas le niveau d'erreur pour toutes les conditions d'erreur (par exemple pour l'accès refusé) – jhyot

-2

Salut Cela devrait fonctionner aussi bien

@echo off 

for /f %%i in ('del notepad2.exe 2^>^&1') do set ERRORLEVEL=1 
IF %ERRORLEVEL%=1 then exit 
+3

Vous ne devriez jamais *** définir directement la variable ERRORLEVEL. valeur% remplacera la valeur dynamique.% ERRORLEVEL% 'ne rapportera plus le code d'erreur retourné de la ou des commandes précédentes, mais à la place il s'étendra à la valeur que vous avez définie. – dbenham

0

Ceux-ci semblent travailler pour moi:

RD:

FOR /D %d IN (*) DO (RD /S /Q "%d" & IF EXIST "%d" EXIT /B 1) 

DEL:

FOR %f IN (*.*) DO (DEL /Q "%f" & IF EXIST "%f" EXIT /B 1) 

Aucune idée sur les performances bien.

Vous pouvez ajouter un indicateur/F à DEL pour un mode «forcer la suppression».

1

Juste pour votre information. La commande DEL renvoie un code d'erreur si une erreur grave se produit, mais son comportement est bien au-delà de notre intuition que les gens croient simplement que le code d'erreur ne fonctionne pas du tout.

C'est ce que je l'ai testé dans la commande DEL dans Windows 7:

  • suppression réussie de tous les fichiers: 0 (bien sûr)
  • Certains fichiers supprimés, certains fichiers manquants: 0 (intuition attend 1)
  • échec de suppression en raison sans autorisation ou en lecture seule moyenne: 0 (intuition attend ≥ 1)
  • lecteur inexistante ou un lecteur pas prêt (par exemple pas de CD sur un lecteur de CD-ROM): 1 (oui, vous l'obtenez, mais je m'attends à un code d'erreur plus élevé)
  • chemin non valide: 1 (j'attendre à un plus haut code d'erreur, aussi)

Et, si vous spécifiez une liste de fichiers à commande DEL, où au moins l'un des fichiers adapter à la dernière deux types d'erreur mentionnés ci-dessus, puis aucun des fichiers de la liste sera supprimé du tout.

Questions connexes