jueves, 4 de enero de 2018

Apagar el ordenador cuando termina una tarea.

Me encanta robocopy. Tiene sus más y sus menos, claro, pero el hecho de que a partir de XP se incluyera con windows un programa equivalente a Xcopy pero con la capacidad de seleccionar qué copiar, ejecutarse en segundo plano, e incluso hacer copias de seguridad programadas, fue un gran adelanto.

El problema es que, cuando te pones a hacer copias hay muchos tiempos muertos. Y a veces quieres dejar la última copia en ejecución pero deseas que se apague el ordenador al terminar (lo que es muy útil a altas horas de madrugada, cuando el cuerpo pide sueño). No sé por qué no se incluyó esa característica en robocopy (que, por lo demás, está pensado para ejecutarse sin supervisión), o quizá es que no la he encontrado.

Pero, de repente, al ejecutar el administrador de tareas se me ocurrió una idea. Si existiera en windows un administrador de tareas en modo consola, podría consultarlo repetidamente para saber si una tarea sigue en ejecución. Una pequeña búsqueda reveló que ese programa existe, y se llama tasklist. Así que es muy fácil hacer un programa como este para supervisar si robocopy ha terminado o no:

rem Guardar este programa como
rem apaga-al-terminar-robocopy.cmd
rem y ejecutarlo DESPUÉS de iniciar robocopy.
rem
:inicio
tasklist | find /i "robocopy" > estado_robocopy
for %%a in (estado_robocopy) do (
if %%~za.==0. goto :apaga
)
for /L %%f in (1;1;10000) do rem %%f
goto :inicio
:apaga
shutdown -s -t 200
:fin

El programa anterior hace lo siguiente:

  1. Busca la palabra "robocopy" en la lista de tareas, enviando el resultado al archivo "estado_robocopy". Se usa find /i para indicar que no ha de distinguirse entre mayúsculas y minúsculas (el nombre del proceso usa una mezcla de ambas).
  2. A continuación, comprueba el tamaño del archivo. Para obtener el tamaño de archivo, busco un archivo cuyo nombre sea estado_robocopy y devuelvo sus datos en la variable %a (aquí se usa %%a porque se ejecuta desde un script). Se compara %%~za (tamaño del archivo referenciado por %%a) con cero. Si el tamaño es cero, se salta a la etiqueta :apaga, que nos saca del bucle. Se usan los paréntesis para dividir la instrucción en dos líneas.
  3. La segunda instrucción for hace que esperemos un rato antes de volver a comprobar el tamaño de archivo. Básicamente, le decimos al ordenador que cuente hasta diez mil. Esto es importante, porque, como sucedía en Ms-DOS, en algunas versiones de Windows los archivos de intérprete de comandos hacen un uso intensivo del disco, y ese for nos libera tiempo para que robocopy pueda trabajar mientras tanto.
  4. Después del tiempo de espera, salto a la etiqueta :inicio, con lo que todo el proceso vuelve a comenzar de nuevo.
  5. A la etiqueta :apaga se llega solo en caso de que el archivo estado_robocopy tenga un tamaño cero, es decir, cuando robocopy ya no esté en la lista de tareas. Y va seguido de una instrucción shutdown -s -t 200, que apagará el equipo dejando un tiempo de gracia de 200 segundos (unos 3 minutos) por si deseamos cancelar el apagado (para ello, deberíamos abrir un intérprete de comandos y ejecutar shutdown -a)

El programa se puede adaptar para que funcione con cualquier tarea cuyo proceso desaparezca al finalizar (normalmente esto solo ocurre con tareas de consola o tareas diseñadas para poder programarse). Para ello, sustituid "robocopy" por el nombre con que la tarea en cuestión aparece en la lista de procesos del sistema (podéis consultarlo con tasklist.exe o con el administrador de tareas, llamado "taskman" o "taskmgr" según la versión de Windows). Aseguráos también de que en vuestro ordenador exista el comando "tasklist".

Y ahora ya podéis dejar la SD de vuestro móvil copiándose en un blu-ray de 50 gigas mientras os vais a dormir...



Podéis leer mis scripts para la línea de comandos en doc.apagada.com

No hay comentarios: