A tarefa para excluir um diretório é executada com sucesso, mas o diretório ainda está lá

1

Eu tenho uma tarefa no agendador de tarefas em um servidor de arquivos do Windows 2012. A tarefa deve excluir o conteúdo de um diretório de acesso geral temporário todos os domingos à noite. Ele é executado nos horários programados e informa o sucesso a cada vez, mas o conteúdo do diretório não está sendo excluído.

A tarefa inclui este arquivo em lote:

D:  
cd D:\Shared\Temp\  
del /Q /F /S "D:\Shared\Temp\*.*"

Este é o xml da tarefa:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2014-06-16T12:13:45.8524361</Date>
    <Author>OFFICE\Administrator</Author>
    <Description>Weekly deletes the contents of the Temp directory</Description>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2014-06-22T20:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Sunday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>OFFICE\Administrator</UserId>
      <LogonType>Password</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>false</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>true</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"D:\IT\tempdelete.bat"</Command>
    </Exec>
  </Actions>
</Task>

Não consigo entender por que essa tarefa não faz o que é suposto fazer. Alguém com mais experiência poderia esclarecer isso?

Atualização 11 de agosto de 2014

Houve outra resposta aqui que sugeriu a seguinte edição no meu comando em lote (não sei por que foi excluído):

D:
cd D:\Shared\Temp\
del /F /S "D:\Shared\Temp\*.*" 1> D:\my.log 2>&1

Este fim de semana eu corri este script. O Agendador de Tarefas ainda está reivindicando que o trabalho terminou com sucesso, mas desta vez eu tenho um arquivo my.log contraditório:

The system cannot find the path specified.

Não consigo ver um erro de definição de caminho no meu script. O caminho especificado está correto.

Devo não alterar o diretório como estados joeqwerty?
ou
Devo definir a alteração do diretório entre colchetes também?
ou o quê?

    
por Montag451 05.08.2014 / 14:10

1 resposta

1

Eu posso pensar em duas possibilidades.

1) Os arquivos estão sendo adicionados após a conclusão da tarefa agendada. Mas eu suspeito que você está verificando os timestamps e vendo datas que antecedem a tarefa. Então, este provavelmente não é o problema.

2) Um ou mais arquivos podem ser bloqueados por outro processo, o que impediria a exclusão.

Infelizmente, o comando DEL não retorna um código de erro se ele falhar. Imprime uma mensagem de erro para stderr, mas o ERRORLEVEL retornado é sempre 0.

Você pode confirmar que os arquivos bloqueados estão causando o problema, redirecionando stderr para o seu comando DEL para um arquivo usando 2>somePath\someFile.log . Quando houver uma falha, você verá uma mensagem de erro como The process cannot access the file because it is being used by another process. no arquivo de log.

Se você quiser detectar e executar uma ação se um ou mais arquivos estiverem bloqueados, use uma variante de Como parar o lote script no del failure .

set "locked="
for /r "D:\Shared\Temp" %%F in (.) do dir /a-d "%F" >nul 2>nul && (ren "%F\*" * || set locked=1)
if defined locked echo Take some action because files are locked.

A renomeação de arquivos para o nome original falhará se um ou mais arquivos estiverem bloqueados. Mas você não deve fazer o teste se não houver arquivos em uma determinada pasta. O comando DIR / A-D detecta se uma determinada pasta contém arquivos. O comando FOR / R itera todas as pastas, incluindo a raiz especificada.

EDITAR

Eu deveria ter lido o link que citei mais adiante. Na parte inferior estão as respostas que fornecem uma maneira mais direta de detectar a exclusão com falha, sem usar um comando extra para detectar arquivos abertos. Basta examinar a saída stderr do comando DEL. Doh!

del /Q /F /S "D:\Shared\Temp\*.*" 2>&1 1>nul | findstr "^" >nul && echo Take action because one or more files were locked and could not be deleted

Esta solução é melhor porque está detectando o erro de DEL diretamente. A procura de arquivos bloqueados como um comando separado pode falhar se o arquivo for bloqueado após a verificação de bloqueio, mas antes da exclusão.

    
por 06.08.2014 / 19:08