Formas de ejecutar comandos en secuencia

Cuando se desea ejecutar una serie de comandos en cierto orden y consecutivamente, es común ingresar uno y según el resultado obtenido ejecutar o no el siguiente.

Para simplificar esta acción hay varias alternativas según lo que deseemos que suceda según el éxito o fallo del anterior:

1. Ejecutar cada comando sin importar el resultado del anterior

Se separan los comandos por ; (punto y coma) y se ejecutan TODOS.

mkdir temp; tar -cvzf temp/app1.tar.gz app1

Se crea el directorio y luego se genera un tar.gz dentro. Si el directorio existe, el primer comando falla pero no importa.

2. Ejecutar cada comando si el anterior fue exitoso

Se separan los comandos por && (operador Y) y se ejecutan hasta que uno falle.

tar -cvzf backup/docs.tar.gz docs_dir && rm -r docs_dir/

Se crea un tar.gz y solo si esta acción es exitosa, se elimina el directorio.

3. Ejecutar cada comando si el anterior falló

Se separan los comandos por || (operador O) y en este caso se detiene en el primer comando que se se ejecute con éxito.

wget http://server1/data.txt || wget http://server1/data.bkp || date >> failed_data.log

Se intenta obtener data.txt, si no es posible, se intenta con data.bkp. Si también falla, en última instancia se agrega a un log la fecha y hora del (doble) intento fallido.

 

Por supuesto, se pueden hacer combinaciones entre los casos:

mkdir check; cd check; wget http://server1/data.txt || wget http://server1/data.bkp && mv data.txt || date >> failed_data.log
  • Se crea el directorio y se lo accede. Si el directorio existe, el primer comando falla pero sigue la ejecución.
  • Se intenta obtener data.txt. Si esta descarga se completa, se detiene la ejecución de comandos.
  • De lo contrario, se intenta obtener data.bkp. Si esta descarga se completa se renombra el archivo a data.txt. Si esta última acción puede realizarse, se detiene la ejecución de comandos.
  • Si no se pudo descargar data.bkp o bien no se lo pudo renombrar, se agrega a un log la fecha y hora del (doble) intento fallido.

 

Importante: en lo casos mencionados, un comando no utiliza la salida del anterior como su entrada.

Tagged with:
Publicado en Linux

Tratar los registros duplicados en un INSERT de Mysql

Es un sentimiento desagradable el hacer una sentencia INSERT y recibir una respuesta del estilo:

ERROR 1062 (23000): Duplicate entry '123' for key 'PRIMARY'

Los registros se consideran duplicados cuando se intenta insertar un registro que tiene un valor igual a uno existente en un campo que posee una PRIMARY KEY o un índice UNIQUE.

Existen 3 alternativas para controlar la forma en que se resolverá la inserción de registros ante la existencia de duplicados. La elección depende de las reglas de negocio principalmente.

INSERT IGNORE

Todos los errores que ocurran durante la inserción serán ignorados y se presentarán como warnings. Se puede decir que se “mantiene el registro existente”.

IGNORE tiene mayor precedencia que el modo estricto, por lo que si ambos aplican y ocurriera un error, se ignoraría.

Ejemplo

Si la tabla de usuarios tiene un índice UNIQUE por el campo login y ya existe el usuario con login jstock:

mysql> INSERT IGNORE INTO usuarios (login, nombre, apellido, estado) VALUES('jstock', 'Juan', 'Stock', 1);
-> Query OK, 0 rows affected (0.00 sec)

se ignora el duplicado, manteniendo los valores previos del registro.

INSERT ON DUPLICATE KEY UPDATE

Si una fila a insertar fuera a causar un error de duplicación, en su lugar se realiza un UPDATE del registro que existía previamente, modificando uno o más campos a la vez (separando con coma cada asignación) según se indique.

La cantidad de filas afectadas que devuelve Mysql es:

  • 1 si se inserta la nueva fila
  • 2 si la fila existente se modifica
  • 0 si la fila existente se modifica a los valores que ya poseía

Ejemplo

Suponiendo que la tabla hits posee la cantidad de veces que se accedió a una página y tiene un índice UNIQUE por el campo pagina, al agregar un registro más para index.html:

mysql> INSERT INTO paginas (pagina,hits) VALUES ('index.hml',1) ON DUPLICATE KEY UPDATE hits=hits+1;

como ya existe un registro previo identificado, lo que sucede es que se actualiza incrementando en uno la cantidad de hits.

Si existe un campo con AUTO_INCREMENT…

al hacer este tipo de INSERT si efectivamente se crea un registro, se genera un nuevo valor para el campo en cuestión. Este se puede obtener a partir de la función LAST_INSERT_ID().

Si el resultado de la sentencia es hacer una actualización del registro, entonces no se puede obtener el id correspondiente con LAST_INSERT_ID(). Para lograr que esta función tenga sentido en este caso, agregamos en el UPDATE para el campo con AUTO_INCREMENT (supongamos que sea id):

id=LAST_INSERT_ID(id)

Así se logra que la función devuelva el mismo valor que se le pasa como argumento y sea recordado y devuelto por la siguiente invocación de LAST_INSERT_ID().

Ejemplo

mysql> INSERT INTO paginas (pagina,hits) VALUES ('index.hml',1) ON DUPLICATE KEY UPDATE id_pagina=LAST_INSERT_ID(id_pagina), hits=hits+1;

REPLACE

Funciona como INSERT, pero si se detecta un duplicado, se borra el registro existente en la tabla y se realiza la nueva inserción. Se puede decir que se “establece el registro nuevo”, quitando el previo. Al realizar un borrado se desencadenan los triggers asociados al DELETE y los registros vinculados por FOREIGN KEYS podrían borrarse también!

Los pasos que sigue esta sentencia al ejecutarse son:

  1. Intenta insertar el registro
  2. Si falla por duplicate entry de una key
    1. Borra el registro conflictivo de la tabla
    2. Intentar insertar el registro nuevamente

entonces, en caso de fallo por duplicado realiza la secuencia INSERT – DELETE – INSERT.

La cantidad de filas afectadas que devuelve Mysql es:

  • 1 si se inserta la nueva fila (no existía duplicado)
  • 2 si se detecta un duplicado: un registro borrado y uno insertado en su lugar
  • N>2 si hay duplicados debido a múltiples índices UNIQUE por ejemplo

Ejemplo

Si la tabla de usuarios tiene un índice UNIQUE por el campo login y ya existe el usuario con login jstock:

mysql> REPLACE INTO usuarios (login, nombre, apellido, estado) VALUES('jstock', 'Juan', 'Stock', 1);
-> Query OK, 2 rows affected (0.00 sec)

se borra el registro previo y se inserta el nuevo, con los valores indicados.

Si existe un campo con AUTO_INCREMENT…

al hacer el REPLACE en caso de que se detecte un duplicado, se genera un nuevo valor para el campo en cuestión en el registro insertado. Este se puede obtener a partir de la función LAST_INSERT_ID().

Tagged with: , , ,
Publicado en Aplicaciones

Palabras reservadas en Mysql

Particulamente cuando deseamos utilizar ciertas palabras para nombrar tablas y campos, recibimos un mensaje de error del estilo

ERROR 1064 (42000): You have an error in your SQL syntax

esto se debe a que esas palabras son reservadas para Mysql por lo que no se pueden utilizar directamente y deben ser indicadas entre comillas del tipo backticks `.

Las palabras reservadas van cambiando con las versiones de Mysql por lo que deberán investigar cuales aplican a la versión que poseen.

Ejemplo:

mysql > CREATE TABLE schemas (id INT, name VARCHAR(50) );

producirá un error de sintaxis.

Para evitarlo debemos indicar el nombre de tabla entre `

mysql > CREATE TABLE `schemas` (id INT, name VARCHAR(50) );

 

Cuando se trata de campos también es viable utilizar nombres calificados, indicando:

nombre_tabla.nombre_campo

Tagged with:
Publicado en Aplicaciones

Verificar la configuración de Apache

Si hemos modificado la configuración de Apache y a partir de ese momento no inicia normalmente, es posible que hayamos cometido un error en alguna línea de algunos de los archivos correspondientes.

Para detectar donde está el inconveniente lo recomendable es probar la configuración. A continuación detallo la tarea en Windows:

  • Abrir el menú Inicio
  • Buscar la carpeta de Apache
  • Elegir el acceso directo Test Configuration

Si existe un error entonces se mostrará en una ventana de la línea de comandos. De lo contrario, se cerrará automáticamente.

Podemos ejecutarlo por línea de comandos conociendo la ubicación donde se encuentra instalado Apache (de manera similar se puede hacer en Linux).

Si todo funciona correctamente podremos ver algunos warnings y al final el texto:

Syntax OK

Ejemplo:

“C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe” -w -t -f  “C:\Program Files (x86)\Apache Software Foundation\Apache2.2\conf\httpd.conf” -d “C:\Program Files (x86)\Apache Software Foundation\Apache2.2.”

donde se utilizan los siguientes parámetros:

  • -d <DIRECTORIO>: indica un ServerRoot alternativo
  • -f <ARCHIVO>: indica un archivo de configuración alternativo
  • -w: mantener abierta la ventana de la consola ante un error
  • -t: verificar la sintaxis de los archivos de configuración
Tagged with: ,
Publicado en Aplicaciones

Cuando Apache no inicia porque Skype se ejecuta primero

Cuando en la misma computadora conviven Skype y Apache podemos llegar a tener inconvenientes porque ambos utilizan el puerto 80 para sus conexiones. El puerto 80 es el puerto en el que por defecto Apache escucha las conexiones mientras que Skype lo utiliza como un puerto adicional o de respaldo. Contemplar que no sea un error de configuración de Apache el que no permite iniciarlo!

El problema se produce si:

  • Apache está configurado para escuchar en el puerto 80
  • Skype se inicia antes que Apache, por lo que se le asigna el puerto
  • Apache no puede iniciar

Cuando intentamos iniciar Apache desde la línea de comandos de Windows veremos el siguiente error:

net start apache2.2
El servicio de Apache2.2 está iniciándose.
El servicio de Apache2.2 no ha podido iniciarse.
Error específico del servicio: 1.
Puede obtener más ayuda con el comando NET HELPMSG 3547.

Para solucionarlo tenemos 3 alternativas:

1. Cambiar configuración de Skype

Dado que Skype utiliza el puerto 80 como un adicional, esta es la solución recomendada por mí. Para ello:

  1. Iniciar sesión en Skype
  2. Acceder al menú Herramientas > Opciones
    • o bien, presionar Ctrl + ,
  3. Abrir la opción Avanzada > Conexión
  4. Desmarcar la opción “Usar los puertos 80 y 443 para conexiones entrantes adicionales”
  5. Confirmar con Guardar

Si vemos que Skype permite las comunicaciones correctamente, y podemos iniciar el servicio de Apache, entonces damos por solucionado el problema.

Es posible que en ciertos entornos no sea una solución aplicable por políticas de seguridad de la red interna que no permitan conexiones en el puerto configurado de Skype, pero sí en alguno de los adicionales (80 o 443).

2. Cambiar el puerto de Apache

Si es posible utilizar un puerto alternativo para Apache, y nuestra aplicación web lo soporta, entonces podemos optar por esta solución. De lo contrario paramos a la última opción.

  1. Abrir con un editor de textos el archivo: conf\httpd.conf en la ubicación donde instalamos Apache
  2. Modificar en la línea que indica “Listen 80” el 80 por otro número de puerto, por ejemplo el 8080
  3. Cambiar el puerto en cada uno de los VirtualHost definidos, si es que los tenemos
  4. Reiniciar el servicio de Apache para que tome la nueva configuración.

Recordar que puede ser necesario desbloquear acceso el web a nuestro equipo, permitiendo el acceso a través del nuevo puerto en el Firewall de Windows.

3. Asegurarse que Apache inicie antes que Skype

Si el problema se debe a que ambas aplicaciones inician automáticamente con Windows, hasta el momento no conozco una forma de lograr (y asegurar) que Apache lo haga ANTES que Skype. Es por eso que en este caso extremo habrá que configurar que Skype no se inicie automáticamente con Windows y dejar que Apache sí lo haga.

Para cambiar esta configuración de Skype:

  1. Iniciar sesión en Skype
  2. Acceder al menú Herramientas > Opciones
    • o bien, presionar Ctrl + ,
  3. Abrir la opción General > Configuración General
  4. Desmarcar la opción “Ejecutar Skype al encender el equipo”
  5. Confirmar con Guardar y reiniciar el equipo

De esta manera Apache adquiere el puerto 80 y luego Skype no puede utilizarlo, pero sí podría utilizar el 443 si mantuvimos la configuración inicial.

Basado en:

http://www.ehow.com/info_12216304_apache-conflict-skype.html

Tagged with: , , ,
Publicado en Aplicaciones

Proteger las contraseñas guardadas en Firefox con una contraseña maestra

Cada vez que guardamos una clave en Firefox, la misma está disponible para cualquier otra persona que tenga acceso al navegador. La solución más drástica sería desactivar el guardado de contraseñas en Firefox, pero como es algo realmente útil vamos a ir por otro camino.

Un usuario puede acceder a las contraseñas guardadas desde:

  • Botón de identidad del sitio: icono a la izquierda de la url en la barra de direcciones
    1. Presionar el icono
    2. Presionar el botón “Más información…”
    3. Presionar el botón “Ver contraseñas guardadas” en la solapa Seguridad
  • Opciones
    • Abrir el menú Herramientas > Opciones
    • Presionar el botón “Contraseñas guardadas” en la solapa Seguridad

Una vez allí, al presionar “Mostrar contraseñas” solicita una simple confirmación y listo, tenemos a la vista TODAS las contraseñas almacenadas en el navegador.

Adcionalmente, tenemos que saber que aún sin conocer las contraseñas, con el solo hecho de ingresar al login de un sitio donde se hayan almacenado las credenciales de acceso, podremos ingresar!

Para protegernos de ambos casos, Firefox provee de la posibilidad de establecer una contraseña maestra, la cual se solicitará antes de:

  • utilizar las credenciales guardadas para completar los campos de un formulario de login
  • mostrar las contraseñas guardadas

Para configurarla debemos:

  • Abrir el menú Herramientas > Opciones
  • Marcar la opción “Usar una contraseña maestra” en la solapa Seguridad
  • Ingresar la contraseña nueva y su confirmación
  • Confirmar con Aceptar la creación
  • Aceptar nuevamente para completar el cambio de las opciones
Tagged with: , ,
Publicado en Navegadores

Cambiar la aplicación para hacer diff y merge en TortoiseCVS

Teniendo el cliente TortoiseCVS instalado para trabajar con repositorios CVS, podemos cambiar la aplicación para determinar las diferencias (diff) y para combinar (merge) diferentes revisiones del código. Para ello debemos modificar la configuración de la siguiente manera:

  1. Abrir un explorador de windows
  2. Click derecho sobre un lugar vacío
  3. Elegir la opción CVS > Preferences…
  4. Abrir la pestaña Tools
  5. Asociar el ejecutable asociado a Diff application
    • Ajustar el formato de Two-way diff parameters
  6. Asociar el ejecutable asociado a Merge application
    • Ajustar el formato de Two-way merge parameters
  7. Confirmar con OK

Ejemplo:

Si deseamos usar Winmerge para ambas tareas, lo más probable es que configuremos:

C:\Program Files (x86)\WinMerge\WinMergeU.exe

La forma en que vienen especificados los parámetros por defecto es la que utiliza Winmerge, por lo que no es necesario hacer cambios.

Tagged with: , ,
Publicado en Aplicaciones