Apagar ordenador automáticamente tras finalizar proceso

A veces queremos apagar el ordenador, pero hay una tarea en curso (p. ej., una descarga, actualización...). Podemos esperar a que termine para apagar el ordenador manualmente o podemos decirle al ordenador que se apague cuando se complete el proceso. En este artículo os muestro cómo realizar la solución automatizada.

Este artículo puede resultar peligroso si copias las instrucciones a mano y cometes un error, pues se puede apagar el ordenador. Recomiendo leer y comprender las instrucciones aquí mostradas antes de copiarlas literalmente.

Supongamos que hemos realizado una descarga con el programa wget y sabemos que la descarga se completará en una hora aproximadamente. Podríamos programar el apagado del ordenador entonces para dentro de una hora con la instrucción shutdown +60, aunque siempre es recomendable dejar algo más de tiempo.

Este enfoque tiene el grave inconveniente de que, si por alguna razón la tarea se retrasa, es posible que la descarga no se complete. Para solucionar este problema, vamos a hacer que se apague el ordenador cuando la tarea se haya completado.

Cada tarea tiene asignado un identificador de proceso (abreviado PID). Para obtener el número de proceso de un programa podemos utilizar la instrucción pgrep, pasándole como argumento el nombre del programa.

$ pgrep wget
3204

El programa devuelve un estado de salida de cero (éxito) y muestra el resultado de la ejecución (3204). Si no hay ningún proceso que contiene la cadena wget en ejecución, pgrep devuelve un estado de salida de 1.

A continuación, vamos a escribir un bucle con while para que compruebe si pgrep devuelve 0 como estado de salida cada cinco segundos. Si no lo hace, apagamos el ordenador. En el código, abajo, hacemos uso del operador de lista ||. La instrucción que haya antes de || se ejecutará siempre; la que haya después solo se ejecutará si la anterior falla. Como pgrep muestra la salida de la instrucción por pantalla y no me interesa verla cada 5 segundos, la redirijo a /dev/null con > (esto hace que se deseche).

while true; do
    pgrep wget > /dev/null || shutdown now
    sleep 5
done

Si estas instrucciones se van a ejecutar muchas veces, es recomendable programar un guion que nos permita pasarle un parámetro para indicar el programa que queremos controlar.

El método anterior supone problemas para casos en los que pgrep devuelve más de un resultado, pero se puede solucionar controlando solo el identificador del proceso que nos interesa y comprobando que este aún se esté ejecutando. Vamos a imaginar que solo queremos detener el proceso con el identificador número 1091 para los siguientes ejemplos.

Podemos comprobar si un proceso sigue en ejecución analizando la salida del programa ps con la opción -q, y el número de proceso como su argumento.

while true; do
    ps -q 1091 > /dev/null || shutdown now
    sleep 5
done

En GNU/Linux, los procesos crean un directorio, cuyo nombre es el identificador del proceso, dentro del directorio /proc/. Es decir, el proceso con el identificador 1091 tiene asignado el fichero /proc/1019. Una vez que finalice el proceso desaparecerá dicho directorio.

while true; do
    test -d /proc/1091 || shutdown now
    sleep 5
done

Con cualquiera de los anteriores métodos es sencillo programar el apagado del ordenador tras completar una tarea. Aunque no es muy probable, ten en cuenta que cualquier otro nuevo proceso podría obtener el identificador de proceso de la instrucción que estás controlando —por ejemplo, esto se puede hacer usando la instrucción integrada de Bash exec—.

Comentarios