Cómo manejar el Cron de Linux con PHP

Balu15 Abril 2011 - 7:51pm 3 comentarios
Enviar por Email Imprimir

Cómo manejar el Cron de Linux con PHPEn un artículo anterior les comentaba todo lo referente al manejo de tareas con el Cron de Linux; ahora, siguiendo los tips de nettuts, vamos a enfocarnos en como administrar el Cron de Linux con PHP.

Cómo ya mencionabamos, el Crond es un demonio o servicio del sistema Linux que facilita la programación y ejecución de tareas repetitivas mediante la configuración de un archivo llamado crontab. En esta misma línea, Crontab también es un comando que nos permite añadir, actualizar o retirar tareas del Cron de Linux.

En este artículo, vamos a crear una clase PHP que, utilizando una conexión segura, nos proporcionará el medio para manipular Crontab.

Nota: Si deseas conocer más sobre el manejo del cron de linux, te recomiendo el artículo: Cómo añadir tareas al Cron de Linux...

Paso 1: Planificación

Con la finalidad de gestionar el Crontab con PHP, vamos a necesitar poder ejecutar comando en el servidor remoto, como el usuario a quien le pertenece el crontab que se está editando. Afortunadamente, PHP nos proporciona una forma sencilla de hacer esto a través de la biblioteca SSH2. Así pues, ha asegurarse de tener la librería libssh2 instalada.

Bien, empezaremos nuestra clase declarando cuatro propiedades privadas:

  • $connection, que representa la conexión / recurso.
  • $path, que representará la ruta al archivo.
  • $handle, que representará el nombre de nuestro archivo cron temporal.
  • $cron_file, que representa la ruta completa y nombre del archivo cron temporal.

Nuestra clase deberá ser capaz de conectarse y autenticarse, con el fin de ejecutar comandos y acceder al crontab del usuario. Por lo tanto, vamos a establecer una conexión SSH2 y autenticarnos con el constructor.

Con una conexión autenticada, necesitaremos un método para controlar la ejecución de los comandos. Vamos a nombrar a este método: exec(). Generalmente, vamos a llamar a este método desde el interior de la clase, cuando tengamos que ejecutar un comando en el servidor remoto.

Luego, necesitamos poder escribir el crontab en un archivo, por lo que deberemos tener acceso a él. También necesitaremos una forma de eliminar este archivo cuando hayamos terminado con él. Los métodos que utilizaremos para estas funciones los llamaremos write_to_file() y remove_file().

También necesitamos una manera de crear y remover tareas del cron. Por lo que definiremos los métodos append_cronjob() y remove_cronjob, respectivamente.

Hasta aquí podemos eliminar una tarea del cron (la última), pero podemos necesitar poder eliminar el cronTab completo, para ello crearemos el método remove_crontab().

Finalmente, crearemos dos métodos de ayuda (helpers). El primero será para devolver un valor booleano, que simplemente comprobará la existencia del archivo temporal de cron. Y el segundo para mostrar mensajes de error cuando algún error ocurra en el proceso. Llamaremos a estos métodos crontab_file_exists() y error_message(), respectivamente.

	Class Ssh2_crontab_manager {

		private $connection;
		private $path;
		private $handle;
		private $cron_file;

		function __construct() {...}

		public function exec() {...}

		public function write_to_file() {...}

		public function remove_file() {...}

		public function append_cronjob() {...}

		public function remove_cronjob() {...}

		public function remove_crontab() {...}

		private function crontab_file_exists() {...}

		private function error_message() {...}

	}

Paso 2: El constructor

El constructor de la case será el encargado de establecer y autentica la conexión SSH2. Se utilizarán cuatro argumentos, cada uno de ellos tendrá un valor predeterminado de NULL:

  • $host, representa la dirección IP del servidor remoto que desea conectarse
  • $port, es el puerto que se utilizará para la conexión SSH2
  • $username, representará el nombre del usuario para acceder al servidor
  • $password, representa la contraseña del usuario para acceder al servidor.
function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL) {...}

Dentro del constructor, la primera propiedad que vamos a definir es $this->path que representará "el "directorio por defecto" de nuestros archivos cron temporales. Para ello nos serviremos de las funciones strrpos() y substr().

	function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
	{
		$path_length = strrpos(__FILE__, "/");
		$this->path  = substr(__FILE__, 0, $path_length) . '/';
	}

Ahora, definiremos el nombre del archivo por defecto del cron temporal como $this->handle y luego lo concatenaremos con el path, en la propiedad $this->cron_file.

	function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
	{
		$path_length     = strrpos(__FILE__, "/");
		$this->path      = substr(__FILE__, 0, $path_length) . '/';
		$this->handle    = 'crontab.txt';
		$this->cron_file = "{$this->path}{$this->handle}";
	}

Con estas propiedades definidas, podemos realizar nuestra conexión al servidor y autenticarnos. Ahora añadiremos algún manejo de errores básico y lanzamiento de excepciones para proveer al usuario de la clase un feedback muy específico.

Con el bloque try, comprobamos que todos los argumentos han sido definidos. La función is_null() nos devuelve verdadero o falso. Si un argumento es NULL, lanzaremos una excepción con el mensaje apropiado.

	function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
	{
		$path_length     = strrpos(__FILE__, "/");
		$this->path      = substr(__FILE__, 0, $path_length) . '/';
		$this->handle    = 'crontab.txt';
		$this->cron_file = "{$this->path}{$this->handle}";

		try
		{
			if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");
		}
		catch
		{

		}
	}
			

A continuación, definiremos la propiedad $this->connection pasando los argumentos $host y $port a la función ssh2_connect(), la cual establecerá la conexión remota al servidor y devolverá el recurso o FALSE si la conexión falla.

Como utilizamos nuestro propio sistema para manejar los errores, vamos a utilizar el operador @ que suprime los mensajes de error propios de la función PHP. Si la conexió no se realiza correctamente, lanzaremos una excepción con un mensaje de error apropiado.

	function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
	{
		$path_length     = strrpos(__FILE__, "/");
		$this->path      = substr(__FILE__, 0, $path_length) . '/';
		$this->handle    = 'crontab.txt';
		$this->cron_file = "{$this->path}{$this->handle}";

		try
		{
			if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");

			$this->connection = @ssh2_connect($host, $port);
			if ( ! $this->connection) throw new Exception("The SSH2 connection could not be established.");
		}
		catch
		{

		}
	}
			

Ahora, vamos a intenta autenticarnos e iniciar sesión con la función ssh2_password() utilizando el recurso o instancia, el nombre de usuario y contraseña como parametros. La función nos devolverá un valor booleano, que representa el estado de la autenticación. Nuevamente, podemos lanzar un error si algo falla en el proceso de autenticación.

	function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
	{
		$path_length     = strrpos(__FILE__, "/");
		$this->path      = substr(__FILE__, 0, $path_length) . '/';
		$this->handle    = 'crontab.txt';
		$this->cron_file = "{$this->path}{$this->handle}";

		try
		{
			if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");

			$this->connection = @ssh2_connect($host, $port);
			if ( ! $this->connection) throw new Exception("The SSH2 connection could not be established.");

			$authentication = @ssh2_auth_password($this->connection, $username, $password);
			if ( ! $authentication) throw new Exception("Could not authenticate '{$username}' using password: '{$password}'.");
		}
		catch
		{

		}
	}
			

Finalmente, en el bloque catch, PHP tratará de encontrar una coincidencia por cada excepción que uno lance, pasándole un objeto Excpetion, que contendrá un número de propiedades útiles. Por lo cual, vamos a utilizar el método getMessage() propio del objeto Exception, para acceder y mostrar el mensaje definido en la excepción.

Si se fijan en el siguiente código, observarán que estamos mostrando el mensaje de error, llamando al método error_message() de nuestra clase. El método aún no esta definido, pero simplemente mostrará el mensaje de error de una manera ordenada.

	function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
	{
		$path_length     = strrpos(__FILE__, "/");
		$this->path      = substr(__FILE__, 0, $path_length) . '/';
		$this->handle    = 'crontab.txt';
		$this->cron_file = "{$this->path}{$this->handle}";

		try
		{
			if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");

			$this->connection = @ssh2_connect($host, $port);
			if ( ! $this->connection) throw new Exception("The SSH2 connection could not be established.");

			$authentication = @ssh2_auth_password($this->connection, $username, $password);
			if ( ! $authentication) throw new Exception("Could not authenticate '{$username}' using password: '{$password}'.");
		}
		catch (Exception $e)
		{
			$this->error_message($e->getMessage());
		}
	}
			

Paso 3. Ejecutar múltiples comandos

Este método será el responsable de ejecutar comandos en el servidor remoto. Es comparable al ingreso manual de comando en el shell de linux con PuTTY. Para obtener un mayor grado de flexibilidad, este método será público por lo que los usuarios de la clase podrán ejecutar otros comandos que necesiten. Asimismo, no limitaremos el número de argumentos a uno en específico. Estos argumentos representarán los comandos que queremos se ejecuten usando la función ssh2_exec().

Entonces, lo primero que haremos con este método es definir una variable que represente la cuenta del número total de argumentos que son pasados. Para esto usaremos la función func_num_args().

	public function exec()
	{
		$argument_count = func_num_args();
	}
  

Ahora, dentro del bloque try, comprobaremos que el método sólo se ejecute cuando se hayan pasado argumentos. Si el número de argumentos es 0, lanzaremos una excepción con un mensaje apropiado.

	public function exec()
	{
		$argument_count = func_num_args();

		try
		{
			if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");
		}
		catch
		{

		}
	}

Acto seguido, usando la función func_num_args() crearemos un array con todos los argumentos que fueron pasados al método.

Usando un operador ternario, definiremos una nueva variable: $command_string, una simple línea de texto que representará los comandos de Linux que serán ejecutados.

Si tenemos múltiples comandos a ejecutar, usaremos la función de PHP implode() para parsear los elementos del array en un string. Separaremos cada elemento con el operador Linux &&, el cual permite la ejecución de múltiples comandos, secuencialmente, en una línea.

Caso contrario, si sólo hay un comando, definiremos el string del comando en $arguments[0], el cual representa el primer y único argumento/comando.

	public function exec()
	{
		$argument_count = func_num_args();

		try
		{
			if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");

			$arguments = func_get_args();

			$command_string = ($argument_count > 1) ? implode(" && ", $arguments) : $arguments[0];

		}
		catch
		{

		}
	}

Con nuestros comandos listos y parseados como un string, ahora podemos ejecutarlos. Le pasaremos el enlace de conexión, $this->connection, y nuestro $command_string a la función ssh2_exec() y esta nos devolverá un valor booleano, en caso se ejecute con éxito o no.

	public function exec()
	{
		$argument_count = func_num_args();

		try
		{
			if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");

			$arguments = func_get_args();

			$command_string = ($argument_count > 1) ? implode(" && ", $arguments) : $arguments[0];

			$stream = @ssh2_exec($this->connection, $command_string);
			if ( ! $stream) throw new Exception("Unable to execute the specified commands: {$command_string}");

		}
		catch
		{

		}
	}

Aquí también utilizamos el operador @ para suprimir cualquier mensaje de error, ya que utilizamos nuestro propio sistema de manejo de excepciones.

	public function exec()
	{
		$argument_count = func_num_args();

		try
		{
			if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");

			$arguments = func_get_args();

			$command_string = ($argument_count > 1) ? implode(" && ", $arguments) : $arguments[0];

			$stream = @ssh2_exec($this->connection, $command_string);
			if ( ! $stream) throw new Exception("Unable to execute the specified commands: {$command_string}");

		}
		catch
		{
			$this->error_message($e->getMessage());
		}

		return $this;
	}

Paso 4. Escribiendo el CronTab a un fichero

El siguiente método write_to_file(), será el responsable de escribir el cronTab existente en un archivo temporal o de crear uno en blanco, en caso no hayan tareas para el Cron. Tomará dos argumentos:

  • El path del archivo temporal que será creado
  • El nombre que será utilizado cuando lo creemos

Continuando con la lógica de nuestros métodos constructor y exec, definiremos los valores por defecto de estos argumentos como NULL.

	public function write_to_file($path=NULL, $handle=NULL)
	{

	}

Lo primero que debemos hacer en este método es comprobar que el archivo de cron existe usando el método booleano crontab_file_exists(), el cual crearemos en breve. Si no existe, no es necesario continuar. De lo contrario, utilizaremos un operador ternario para comprobar las variables $path y $handle son o no Nulas.

Luego, concatenaremos esta propiedades y crearemos una nueva que representará la ruta completa y el nombre del archivo del fichero cron temporal.

	public function write_to_file($path=NULL, $handle=NULL)
	{
		if ( ! $this->crontab_file_exists())
		{
			$this->handle = (is_null($handle)) ? $this->handle : $handle;
			$this->path   = (is_null($path))   ? $this->path   : $path;

			$this->cron_file = "{$this->path}{$this->handle}";
		}
	}

Luego, usaremos el comando Linux crontab, con el argumento –l, para mostrar el cronTab como salida estándar. Luego, usando el operador de Linux >, redireccionaremos la salida estándar, o STDOUT, a nuestro archivo de cron temporal, con la concatenación de $this->cron_file. Al redirigir la salida de un archivo, usando el operador >, siempre creará un archivo si este no existe.

	public function write_to_file($path=NULL, $handle=NULL)
	{
		if ( ! $this->crontab_file_exists())
		{
			$this->handle = (is_null($handle)) ? $this->handle : $handle;
			$this->path   = (is_null($path))   ? $this->path   : $path;

			$this->cron_file = "{$this->path}{$this->handle}";

			$init_cron = "crontab -l > {$this->cron_file}";
		}
	}

Esto funciona muy bien, pero sólo si hay trabajos programados en el crontab. Si no hay trabajos para el cron, este archivo no se creará. Sin embargo, usando el operador &&, podemos añadir comandos / expresiones adicionales al string. Entonces, vamos a añadirle una expresión condicional para comprobar que el archivo cron existe. Si el archivo no existe, la expresión será evaluada como falsa. En este caso, utilizando el operador condicional ||, podemos crear un nuevo archivo en blanco, de ser necesario.

	public function write_to_file($path=NULL, $handle=NULL)
	{
		if ( ! $this->crontab_file_exists())
		{
			$this->handle = (is_null($handle)) ? $this->handle : $handle;
			$this->path   = (is_null($path))   ? $this->path   : $path;

			$this->cron_file = "{$this->path}{$this->handle}";

			$init_cron = "crontab -l > {$this->cron_file} && [ -f {$this->cron_file} ] || > {$this->cron_file}";
		}
	}

Finalmente, vamos a llamar al método exec() y pasarle la cadena de comandos como único argumento. Luego, para hacer a este método más utilizable, retornaremos un $this.

	public function write_to_file($path=NULL, $handle=NULL)
	{
		if ( ! $this->crontab_file_exists())
		{
			$this->handle = (is_null($handle)) ? $this->handle : $handle;
			$this->path   = (is_null($path))   ? $this->path   : $path;

			$this->cron_file = "{$this->path}{$this->handle}";

			$init_cron = "crontab -l > {$this->cron_file} && [ -f {$this->cron_file} ] || > {$this->cron_file}";

			$this->exec($init_cron);
		}

		return $this;
	}

Paso 5. Eliminar el archivo temporal Cron

El método remove_file() es muy sencillo. Usaremos nuestro método helper, crontab_file_exists(), para comprobar la existencia del archivo temporal Cron y ejecutar el comando Linux rm para borrarlo. Como es usual, devolveremos el valor de $this para mejorar su uso.

	public function remove_file()
	{
		if ($this->crontab_file_exists()) $this->exec("rm {$this->cron_file}");

		return $this;
	}

Paso 6. Crear nuevas tareas del Cron

Este método se encargará de crear nuevas tareas del cron, añadiendo nuevas líneas (tareas) al archivo temporal Cron y luego ejecutando el comando crontab en ese archivo que instalará todas las tareas como un nuevo cronTab. append_cronjob() tomará un argumento, $cron_jobs, que o bien será un string o, de lo contrarío, un array de strings que representarán los trabajos del Cron a anexar.

Empezaremos el método, determinando si el argumento $cron_jobs es NULL, para llamar al método error_message(), a fin de que corte la ejecución del programa y muestre un mensaje de error al usuario.

	public function append_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to append!  Please specify a cron job or an array of cron jobs.");

	}

Luego, definiremos una nueva variable, $append_cronfile, como un string, con el texto "echo" seguido de un espacio y una comilla simple al final. Combinaremos este string con varios cron jobs hasta cerrar las comillas. Construiremos este string con el operador de concatenación de cadenas .=.

Usando un operador ternario, determinaremos si $cron_jobs es un array o no. Si lo es realizamos un implode para estraer cada tarea (línea nueva) del archivo cron. En caso de que no sea un array, simplemente concatenaremos la tarea con la cadena $append_cron sin ningún procesamiento especial.

El operador >>, a diferencia del operador > que siempre sobre escribe un archivo, añade la salida standard al final del archivo. Por lo que usaremos este operador, para no sobreescribir los cron jobs existentes.

	public function append_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to append!  Please specify a cron job or an array of cron jobs.");

		$append_cronfile = "echo '";	

		$append_cronfile .= (is_array($cron_jobs)) ? implode("\n", $cron_jobs) : $cron_jobs;

		$append_cronfile .= "'  >> {$this->cron_file}";

	}

Antes de ejecutar estos comando vía el método exec(), primero llamaremos al método write_to_file() para crear un archivo cron temporal. Luego, dentro de una cadena, ejecutaremos los comandos y llamaremos al método remove_file() para borrar el archivo temporal. Finalmente, devolveremos $this para que el método append_cronjob() sea reutilizable.

	public function append_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to append!  Please specify a cron job or an array of cron jobs.");

		$append_cronfile = "echo '";		

		$append_cronfile .= (is_array($cron_jobs)) ? implode("\n", $cron_jobs) : $cron_jobs;

		$append_cronfile .= "'  >> {$this->cron_file}";

		$install_cron = "crontab {$this->cron_file}";

		$this->write_to_file()->exec($append_cronfile, $install_cron)->remove_file();

		return $this;
	}

Paso 7. Eliminar Cron Jobs existentes

Ahora que podemos crear nuevos cron jobs, es lógico que deberíamos poder eliminarlos. El método remove_cronjob() tiene un argumento que será una expresión regular. Este regEx será usado para encontrar tareas que coincidan con la expresión, en el crontab, y los elimine. Al igual que con el método append_cronjob(), lo primero que haremos será comprobar si el argumento $cron_jobs es NULL. Si no lo es, llamaremos al método write_to_file() para escribir nuestro cron tab en un archivo.

	public function remove_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

		$this->write_to_file();

	}

Con el cron file creado, lo leeremos y almacenaremos en un array, utilizando la función de PHP file(). El flag FILE_IGNORE_NEW_LINES fuerza a file() a ignorar todas las líneas nuevas. Por ende, sólo tendremos una matriz con sus propios cron jobs!

Si el archivo no tiene tareas almacenadas, no hay motivo para borrarlo. Por eso, comprobamos que $cron_array no este vacío y su ejecución dependa de ello.

Si no esta vacío, contaremos los elementos de $cron_array usando la función PHP count() y almacenaremos su valor en $original_count. Luego lo usaremos, para determinar si hemos eliminado algún cron job de $cron_array.

	public function remove_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

		$this->write_to_file();

		$cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

		if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

		$original_count = count($cron_array);

	}

Ahora, definiremos si $cron_jobs es un array o no. Si lo es, iteraremos sobre él con un loop foreach().

	public function remove_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

		$this->write_to_file();

		$cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

		if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

		$original_count = count($cron_array);

		if (is_array($cron_jobs))
		{
			foreach ($cron_jobs as $cron_regex) $cron_array = preg_grep($cron_regex, $cron_array, PREG_GREP_INVERT);
		}
		else
		{

		}
	}

Si el argumento $cron_jobs no es un array, no realizaremos ninguna iteración. Simplemente, redefinimos $cron_array como el array resultante de la función preg_grep() con el flag PREG_GREP_INVERT.

	public function remove_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

		$this->write_to_file();

		$cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

		if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

		$original_count = count($cron_array);

		if (is_array($cron_jobs))
		{
			foreach ($cron_jobs as $cron_regex) $cron_array = preg_grep($cron_regex, $cron_array, PREG_GREP_INVERT);
		}
		else
		{
			$cron_array = preg_grep($cron_jobs, $cron_array, PREG_GREP_INVERT);
		}
	}

Con nuestra variable $cron_array definida, ahora compararemos el tamaño actual del array con el tamaño original que fue capturado en la variable $original_count. Si el tamaño es el mismo, simplemente devolveremos el método remove_file() para borrar el archivo cron temporal. Si no coinciden, removeremos el cronTab existente y luego instalaremos uno nuevo.

Los métodos remove_file(), remove_crontab() y append_cronjob() devolverán $this, por lo que al utilizarlos siempre preservaremos su chainability.

	public function remove_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

		$this->write_to_file();

		$cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

		if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

		$original_count = count($cron_array);

		if (is_array($cron_jobs))
		{
			foreach ($cron_jobs as $cron_regex) $cron_array = preg_grep($cron_regex, $cron_array, PREG_GREP_INVERT);
		}
		else
		{
			$cron_array = preg_grep($cron_jobs, $cron_array, PREG_GREP_INVERT);
		}	

		return ($original_count === count($cron_array)) ? $this->remove_file() : $this->remove_crontab()->append_cronjob($cron_array);
	}

Paso 8. Borrar el Crontab completo

Borrar el cronTab completo es relativamente sencillo de hacer. Básicamente, sólo debemos ejecutar el comando crontab con el parámetro –r, el cual se encargará de el crontab entero del usuario. Una vez que el crontab es reseteado, podemos eliminar el archivo temporal del cron, si es que existe. Luego, retornamos $this.

	public function remove_crontab()
	{
		$this->exec("crontab -r")->remove_file();

		return $this;
	}

Paso 9. Algunos métodos útiles

Con la mayor parte de nuestra clase escrita, ahora daremos una mirada a dos pequeños, pero útiles, métodos que usaremos en nuestra clase: cronta_file_exists() y error_message().

$this->crontab_file_exists()

Este método simplemente devolverá el resultado de la función PHP file_exists(), verdadero o falso, dependiendo de si el archivo temporal cron existe o no.

	private function crontab_file_exists()
	{
		return file_exists($this->cron_file);
	}

$this->error_message($error)

Este método tomará un argumento, un string, que representará el mensaje de error que queremos mostrar. Luego, llamaremos a la función PHP die() para ejecutar y mostrar su mensaje. El string, será concatenado dentro de una etiqueta <pre> con un estilo css simple.

	private function error_message($error)
	{
		die("ERROR: {$error}");
	}

Paso 10. Poniendo todo junto

Ahora que hemos completado esta clase PHP para administrar el Cron de Linux, daremos una mirada a algunos ejemplos de uso.

Inicializar la clase y establecer una conexión autenticada

Primero, creamos una nueva instancia de nuestra clase. Recuerden, necesitamos enviar la dirección IP, puerto, nombre de usuario y contraseña a la clase constructora.

$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');

Añadiendo una tarea al cron

Con una conexión autenticada en su sitio, veremos cómo crear una única tarea del Cron.

		$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');
		$crontab->append_cronjob('30 8 * * 6 home/path/to/command/the_command.sh >/dev/null 2>&1');

Añadiendo un array de tareas al cron

Añadir varias tareas al cron es tan sencillo como añadir una sóla. Simplemente pasamos un array al método append_cronjob().

		$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');

		$new_cronjobs = array(
			'0 0 1 * * home/path/to/command/the_command.sh',
			'30 8 * * 6 home/path/to/command/the_command.sh >/dev/null 2>&1'
		);

		$crontab->append_cronjob($new_cronjobs);

Eliminar una tarea del cron

En este caso, debemos usar una expresión regular para encontrar la tarea apropiada. El regEx puede ser simple o complejo, de acuerdo a nuestras necesidades.

		$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');

		$cron_regex = '/home\/path\/to\/command\/the_command\.sh\/';

		$crontab->remove_cronjob($cron_regex);

Eliminar varias tareas del cron

Eliminar varias tareas del cron es tan sencillo como retirar una sóla, con una sóla excepción, necesitamos pasarle un array de expresiones regulares al método remove_cronjob().

		$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');

		$cron_regex = array(
			'/0 0 1 \* \*/',
			'/home\/path\/to\/command\/the_command\.sh\/'
		);

		$crontab->remove_cronjob($cron_regex);

Punto final

¡Eso es todo! En este artículo hemos visto como manejar el Crontab de Linux con una clase PHP. ¡Espero, les sea de utilidad!

Descargar | Código fuente del ejemplo

Fuente | Nettuts: Managing Cron Jobs with PHP

Comentarios

Imagen de kabbal

Hola!
¡Este artículo es fantástico!
Estoy intentando automatizar un envío de mails.
Quiero que al ejecutar el archivo, envíe un mail a 30 suscriptores diferentes cada 5 minutos hasta completar una lista.
Mi mayor problema es eliminar la tarea cuando ya haya completado todos los envíos.
Digamos que en mi BBDD hay una columna llamada "enviado" con valor NULL, y cada vez que la tarea envía un correo "enviado" pasa a 1.
¿cómo puedo hacer para que cuando el php lea que ya no queda ningún "enviado" NULL frene o elimine la rutina de envíos?

gracias

Imagen de Pepe Paco
Pepe Paco

Muy bueno la clase, me ha servido perfectamente.

Pero le hemos econtrado un fallo a la expresion regular que borra los crontabs.

$cron_regex = '/home\/path\/to\/command\/the_command\.sh\/';

La ultima barra invertida de .sh\/ hace que no ecuentre delimitador de final de la expresion y borra todos los crontabs que hubiera en el fichero.

Tener Cuidado !!

$cron_regex = '/home\/path\/to\/command\/the_command\.sh/';

Imagen de Anonymous
Anonymous

Estoy usando el código y está genial. Solo tengo un problema al borrar un crontab
Como tengo que formar las expresiones regulares para comandos como "curl http://www.google.com" y "crontab -l"

Gracias.

Tutoriales

Cómo descargar videos de VK.com
En este artículo voy a explicar como descargar videos y películas...
Descargar Facebook Móvil Gratis
Por si aún no lo han hecho, es posible descargar Facebook Móvil...
Cómo generar tráfico web con las redes sociales - Paso a Paso
Muchas empresas están publicando contenidos como la forma de crear...

Artículo Recomendado

3 Tips cruciales para recuperar archivos eliminados
¿Te imaginas perder el trabajo de toda una semana en tan solo unos segundos? Todos hemos pasado por este problema. Quizás eliminamos por error un archivo importante o lo borramos sin pensar que era valioso para otro... más