Programar la ejecución de un script en Windows

Si queremos que un cierto script se ejecute automáticamente siempre que iniciamos sesión en Windows hay una forma sencilla:

  1. Crear un acceso directo al script (Botón derecho sobre el archivo y luego Crear acceso directo)
  2. Copiar el acceso directo creado al directorio Inicio dentro del Menú inicio:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

Si el momento de ejecución queremos definirlo de manera más precisa podemos utilizar el Programador de tareas:

  1. Acceder a Panel de Control > Herramientas administrativas > Programador de tareas
  2. Elegir la opción “Crear tarea…” del panel derecho de Acciones
  3. Definir un nombre y opcionalmente la descripción en la solapa General
  4. Elegir la solapa Desencadenadores y presionar Nuevo… (se puede agregar más de uno)
  5. Configurar cuándo inicia la tarea y cuándo se repite (ej: Semanalmente, Lunes y Viernes)
  6. Elegir la solapa Acciones y presionar Nuevo… (se puede agregar más de una)
  7. Elegir en Acción: Iniciar un programa y presionar Examinar… para elegir nuestro script
  8. Confirmar con Aceptar

De ahora en adelante nuestro script se ejecutará automáticamente según la periodicidad definida.

Desbloquear acceso web a nuestro equipo en Windows

Si contamos en nuestro equipo con un servidor web (Apache por ejemplo) y brindamos servicios a través de él, es probable que por defecto otros equipos no tengan acceso web al nuestro por seguridad.

Para permitir este tipo de conexiones, debemos agregar una regla al firewall de Windows permitiendo las conexiones que se realicen al puerto que usa nuestros servidor web (por defecto:80). Los pasos son sencillos:

  1. Acceder a Panel de Control > Firewall
  2. Elegir la opción “Configuración avanzada” del panel izquierdo
  3. Seleccionar el item “Reglas de entrada”
  4. Elegir “Nueva regla…” del panel izquierdo de Acciones
  5. Seleccionar la opción “Puerto”
  6. Elegir TCP y completar en Puertos locales específicos con el número de puerto deseado (ej: 80)
  7. Mantenemos la opción “Permitir la conexión”
  8. Elegir el ámbito de aplicación por perfil (recomendación Privado)
    • Dominio: red con un controlador de dominios
    • Privado: red no conectada directamente a Internet, con un dispositivo intermediario que asegura la conexión
    • Público: red conectada directamente a Internet, más insegura
  9. Completar con un nombre claro “Acceso web puerto 80” o “Apache TCP puerto 80”
  10. Terminar el proceso con Finalizar

Desde ahora los accesos a nuestro equipo a través del puerto elegido serán permitidos.

Apagar Windows desde la línea de comandos

Para apagar Windows desde la línea de comandos, utilizamos el comando shutdown con alguno de los parámetros indicados:

shutdown /h

Apaga el equipo inmediatamente

shutdown /s

Apaga el equipo con un tiempo de espera y dando una advertencia al usuario. Se puede cancelar mediante: shutdown /a

 

Hacer un script de respaldo de archivos en Windows

Para poder respaldar todo el contenido de un directorio en un archivo dentro de otra unidad, disco o directorio, podemos crear un script de línea de comandos:

Crear el archivo ejecutable

  1. Abrir un editor de textos de nuestra preferencia (puede ser el Bloc de notas)
  2. Escribir los comandos para realizar cada una de las acciones deseadas
  3. Guardar el archivo con extensión .bat (ejemplo: respaldo.bat)

Desactivar el “eco” de los comandos

Cuando se ejecuta cada uno de los comandos, los mismos se repiten en la línea de comandos por defecto. Para evitar esto debemos comenzar el script con:

@echo off

Obtener la fecha y hora de ejecución

En las variables FECHA y HORA almacenamos sendos datos:

for /f "tokens=1-3 delims=/- " %%a in ('date /t') do set FECHA=%%c%%b%%a
for /f "tokens=1-2 delims=: " %%a in ('time /t') do set HORA=%%a%%b

Generar nombre del archivo de respaldo

Con la fecha y la hora, generamos un nombre de archivo  y lo almacenamos en la variable BACKUP_FILE

set BACKUP_FILE=Contenido_%FECHA%%HORA%.zip

Comprimir los datos

En esta parte se puede utilizar cualquier aplicación que permita comprimir por línea de comandos. Yo les propongo que usen 7zip que es gratuito. Tenemos que especificar la ubicación del archivo de respaldo primero y luego el directorio con el contenido a respaldar:

7zip.exe a -tzip "c:/backups/BACKUP_FILE" "c:/Contenido/"

Registrar log

El registro de log es opcional, pero si vamos a planificar la ejecución del script es conveniente registrarla para poder consultar después si se realizó o no correctamente.

Establecemos el nombre y la ubicación del log relativo a la ubicación en que se encuentre el script de backup. Les propongo generar un log por día y no por ejecución:

set BACKUP_LOG_FILE=logs/Contenido_%FECHA%.log

Al principio del script indicamos el inicio del respaldo con la fecha y hora:

echo. >> %BACKUP_LOG_FILE%
echo Inicia respaldo >> %BACKUP_LOG_FILE%
echo %FECHA% %HORA% >> %BACKUP_LOG_FILE%

Modificamos la línea donde hacemos la compresión para que los resultados de la misma vayan al log

7zip.exe .... >> %BACKUP_LOG_FILE%

Al final del script indicamos el fin del respaldo con la fecha, hora y el archivo de log generado:

echo. >> %BACKUP_LOG_FILE%
echo Fin respaldo >> %BACKUP_LOG_FILE%
echo %FECHA% %HORA% >> %BACKUP_LOG_FILE%
echo Log file: %BACKUP_LOG_FILE%

OBS: El comando “echo.” solamente guarda en el log una línea vacía.

Programar ejecución

Teniendo el script, cada vez que lo ejecutemos, se generará un backup (y un log si así lo decidimos). Para que este backup se ejecute automáticamente hay que programar la ejecución del script en Windows o en Linux.

Script completo

Les dejo el contenido del script completo para que lo puedan copiar y usar como base para generarse el propio:

@echo off

for /f "tokens=1-3 delims=/- " %%a in ('date /t') do set FECHA=%%c%%b%%a
for /f "tokens=1-2 delims=: " %%a in ('time /t') do set HORA=%%a%%b

set BACKUP_FILE=Contenido_%FECHA%%HORA%.zip
set BACKUP_LOG_FILE=logs/Contenido_%FECHA%.log

echo. >> %BACKUP_LOG_FILE%
echo Inicia respaldo >> %BACKUP_LOG_FILE%
echo %FECHA% %HORA% >> %BACKUP_LOG_FILE%

7zip.exe a -tzip "c:/backups/BACKUP_FILE" "c:/Contenido/" >> %BACKUP_LOG_FILE%

echo. >> %BACKUP_LOG_FILE%
echo Fin respaldo >> %BACKUP_LOG_FILE%
echo %FECHA% %HORA% >> %BACKUP_LOG_FILE%
echo Log file: %BACKUP_LOG_FILE%

Permitir acceso mediante Escritorio remoto en Windows 7

Si tenemos varios equipos en una red local con Windows 7 y queremos permitir el acceso a algunos de ellos mediante Escritorio remoto, debemos hacer lo siguiente:

  1. Acceder a Sistema mediante
    • Panel de Control > Sistema
    • Click derecho sobre Equipo > Propiedades
  2. Seleccionar Configuración avanzada del sistema desde el panel izquierdo
  3. Elegir la solapa Acceso remoto
  4. Elegir una de las opciones que permiten las conexiones de Escritorio remoto, con el nivel de seguridad deseado en el apartado Escritorio remoto.
  5. Pulsar “Seleccionar usuarios…” si queremos permitir acceso con usuarios que no sean administradores, y agregarlos
  6. Confirmar con Aceptar

Para revisar que el Firewall permita este servicio:

  1. Acceder a Panel de Control > Firewall de Windows
  2. Elegir “Permitir un programa o una característica…” desde el panel izquierdo
  3. Buscar en el listado “Escritorio remoto”
  4. Tildar la caja de selección “Privada”
  5. Confirmar con Aceptar

Para probar el acceso, desde otro equipo buscamos en Inicio > “Conexión a Escritorio remoto” y lo abrimos. Indicamos el nombre del equipo o su ip, y presionamos Conectar.

Si todo está bien, deberemos ingresar un usuario, y su contraseña, al que hayamos permitido el acceso. Una vez validado, tendremos completo control del equipo huésped como si estuviéramos usándolo directamente.

Actualizar Ubuntu cuando existen inconvenientes

Cada tanto sucede que al intentar actualizar Ubuntu, aparecen conflictos de una actualización previa que falló o no se completó, algún error con el administrador de paquetes, o de actualizaciones, o la indicación que se realizará una actualización parcial.

Para todos esos casos basta con acceder a la línea de comandos e ingresar uno a uno los siguientes comandos:

sudo dpkg --configure -a
sudo apt-get -f install
sudo apt-get --fix-missing install
sudo apt-get clean
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo apt-get clean
sudo apt-get autoremove

 

A continuación, les detallo para qué sirve cada uno:

sudo dpkg –configure -a

Vuelve a configurar todos los paquetes que no estén desempaquetados, completando una actualización que no se terminó.

sudo apt-get -f install

Intenta arreglar dependencias actualmente rotas (fix-broke) permitiendo a APT omitir cualquier paquete para deducir una posible solución.

sudo apt-get –fix-missing install

Obtiene los paquetes que faltan, que no pudieron ser obtenidos o porque falló el chequeo de integridad (paquetes corruptos) y los instala.

sudo apt-get clean

Limpia el repositorio local de paquetes obtenidos

sudo apt-get update

Actualiza el listado de paquetes disponibles en los repositorios indicados en /etc/apt/sources.list

sudo apt-get upgrade

Instala la versión más nueva de todos los paquetes que se encuentren instalados en el sistema, obteniéndola desde los repositorios indicados en /etc/apt/sources.list

sudo apt-get dist-upgrade

De manera similar a ‘apt-get upgrade’, actualiza los paquetes instalados, pero puede instalar nuevos paquetes o quitar algunos de los instalados si es necesario para resolver algunas dependencias importantes.

sudo apt-get clean

Limpia el repositorio local de paquetes obtenidos.

sudo apt-get autoremove

Borra paquete que se instalaron automáticamente para satisfaces algunas dependencias y ya no son requeridos.

Almacenamiento de caracteres en MySQL

En Mysql, los caracteres se almacenan en los campos de tipo CHAR y VARCHAR.

CHAR

  • Tiene una longitud fija (máxima), entre 0 y 255, desde el momento en que se agrega a la tabla.
  • Cuando se guarda un valor, se agregan espacios al final hasta completar la longitud.
  • Cuando se obtiene el valor, los espacios al final se quitan (excepto que esté activado el modo sql PAD_CHAR_TO_FULL_LENGTH)
  • Los espacios finales en exceso en valores insertados son truncados silenciosamente.

VARCHAR

  • Tiene una longitud variable siendo la máxima, entre 0 y 65536.
  • Los valores se almacenan con un prefijo de 1 byte si la longitud es hasta 255 bytes y de 2 bytes si es mayor, además de los datos.
  • Los valores no se completan con espacios cuando se guardan.
  • Los espacios al final se guardan y se obtienen siempre.
  • Los espacios finales que exceden la longitud máxima se truncan antes de la inserción y generan un warning.

En ambos tipos

  • Si no está activado el modo estricto, al asignar un valor a un campo CHAR o VARCHAR que excede su longitud máxima, se trunca y genera un warning. Caso contrario, se genera un error y se anula la consulta.
  • Los valores se ordenan y comparan de acuerdo al collation asociado al campo.
  • Los valores se comparan omitiendo los espacios finales, a excepción de cuando se usa el operador LIKE, para el cual importan los espacios al final.
  • Si un campo tiene un índice que requiere valores únicos, al insertar valores que solamente difieran en los espacios al final se generará un error de duplicate entry que deberá ser tratado.

Cómo copiar archivos y carpetas con nombres largos en Windows

En Windows, no podemos copiar directorios y/o archivos cuya ruta completa es larga, por lo general, más de 254 caracteres.

En esta situación, se puede utilizar el comando robocopy. El mismo viene preinstalado en Windows 7, y se puede instalar en versiones previas.

robocopy <ORIGEN> <DESTINO> [<OPCIONES>]

Algunas opciones interesantes:

  • /S : copia los subdirectorios, sin los vacíos
  • /E : copia los subdirectorios, incluyendo los vacíos
  • /COPYALL : copia toda la información del archivo
  • /MOV : mueve los archivos (los borra el origen luego de copiarlos)

Ejemplo: si tenemos la siguiente estructura

  • c:\
    • dir_origen\
      • ruta_con_mas_de_255_caracteres\
        • archivo.txt

e intentamos copiar el contenido de dir_origen a dir_destino, el sistema no lo permitirá.

Para lograrlo debemos ingresar desde la línea de comandos:

robocopy c:\dir_origen c:\dir_destino /S

Pueden ver más ejemplos de uso de robocopy

Cómo funciona la carga de CPU en Linux

Linux informa la carga de un equipo mediante un indicador que se presenta como la carga de CPU o CPU Load. Cuanto menor sea este valor, mejor.

Este valor es la longitud de la cola de ejecución: la cantidad de procesos que están corriendo junto con los encolados (esperando para ejecutarse).

En lugar de valores puntuales se utilizan 3 promedios (average) en el tiempo: el último minuto, los últimos 5 minutos y los últimos 15 minutos.

Cómo ver el load average

Estos valores se observan al ejecutar uno de estos 2 comandos: uptime o top, de la siguiente manera:

load average: 0.22, 0.85, 0.96

Cómo interpretar el load average

Uno podría pensar que estos promedios representan el número promedio de procesos durante el último minuto, últimos 5 minutos y últimos 15 minutos. Pero NO es tan así. En realidad, el load average es el promedio móvil de la carga exponencialmente amortiguado. ¿Y eso qué significa?

Matemáticamente hablando, los 3 valores brindan un promedio de la carga del sistema desde que el sistema se inició. La diferencia es que cada uno decae exponencialmente a una velocidad diferente:

  • el primer load average está compuesto por el 63% de la carga en el último minuto y el 37% restante de la carga desde que el sistema se inició, excluyendo el último minuto.
  • esos mismos porcentajes se aplican al load average de 5 y 15 minutos, aplicados sobre los últimos 5 o 15 minutos respectivamente

Por lo tanto, el load average del último minuto no solo incluye los últimos 60 segundos de actividad, dado que contempla en su cálculo el 37% de la carga en el pasado, pero podemos decir que se representa en su mayoría información del último minuto.

Análisis con un solo core

Por lo general, se recomienda analizar los valores vinculados a 5 y 15 minutos para tomar decisiones.

En un sistema con un procesador que tiene un solo core (núcleo):

  • Revisar la situación (0.70): si el load average se mantiene sobre 0.70 es recomendable investigarlo.
  • Solucionarlo (1.00): si el load average se sostiene sobre 1.00, es necesario tomar acciones de inmediato.
  • Estamos en problemas (5.00): cuando el load average exceda 5.00 de manera sostenida, el equipo se está colgando o respondiendo cada vez con mayor lentitud.

Como pueden imaginarse, estos valores son subjetivos y pueden ajustarse según las necesidades, una vez que se comprende lo que significan.

Análisis con múltiples cores

El análisis depende de la cantidad de cores de los procesadores que existan en el equipo.

cantidad total de cores del equipo = suma de los cores de cada procesador

Con esta consideración, el 100% de utilización se mostrará con una carga = al total de cores del equipo. Si tenemos 2 cores, la carga será 2.0 y para 4 cores, la carga será 4.0

En un sistema con múltiples cores, la carga nunca debería exceder el número de cores disponibles.

Ejemplo: considerando que tenemos 4 cores en nuestro sistema, si ejecutamos:

$ uptime

18:34:30 up 1:43, 10 users, load average: 4.20, 4.24, 4.31

Viendo el segundo valor (4.24) hemos sobrepasado el primer límite de 2.80 = 4 * 0.70 y como la carga se mantiene constante sobre 4 (cantidad de cores), debemos buscar la causa y evaluar acciones inmediatas. Estaríamos en la peor situación si la carga fuera superior a 20.0 = 4 * 5.0

Este análisis no es preciso

Dado que el número de la carga incluye procesos ininterrumpibles (esperando por disco o red) que no afectan al uso de CPU, el análisis recientemente expuesto no siempre es preciso. En muchos casos esto puede ocasionar load averages muy altos con poca carga en el CPU.

Determinar la cantidad de cores

Para obtener el número preciso de cores del sistema podemos ejecutar:

$ grep 'model name' /proc/cpuinfo | wc -l

o simplemente ejecutando:

$ nproc

Basado en:

http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages

https://peteris.rocks/blog/htop/#load-average

Consultas de textos case sensitive en MySQL

Mysql es por defecto case insensitive (no sensible a las mayúsculas): no diferencia las mayúsculas de las minúsculas. Esto se debe a que tiene configurado inicialmente el collation ‘latin1_swedish_ci’.

mysql> SELECT nombre_usuario FROM usuarios WHERE nombre_usuario LIKE 'al%'; # retorna usuarios con nombres como 'Alberto', 'Álvaro', 'alejo'

Por lo general, cuando hacemos una comparación es muy conveniente este comportamiento dado que no importa la capitalización que usemos, encontraremos los resultados.

 

Tengamos en cuenta que para los campos con caracteres no binarios: CHAR, VARCHAR y TEXT, la comparación depende del collation de los mismos.

En cambio, para los campos binarios: BINARY, VARBINARY y BLOB se utiliza el valor numérico de los bytes en la comparación, por lo que serán case sensitive en el caso de los caracteres.

Si se compara una cadena binaria y una no-binaria, la comparación se realiza como si fueran ambas binarias.

 

Pero en ciertos casos, cuando deseamos comparar los caracteres contemplando su capitalización, podemos optar por alguna de las siguientes alternativas:

  • Usar el operador COLLATE para indicar un collation que sea case sensitive (termina con _cs o _bin)  que pertenezca al juego de caracteres correspondiente a un campo, un valor o a ciertas partes de la consulta.
    • Disponible a partir de Mysql 4.1
  • Usar el operador BINARY sobre el valor o columna en la consulta
  • Cambiar  el collation de la columna CHAR(N), VARCHAR(N) o TEXT mediante un ALTER TABLE por uno que sea case sensitive:
    • agregando BINARY al final, lo cual especifica el collation _bin para el juego de caracteres correspondiente
    • indicando el CHARSET y COLLATION específicos
  • Cambiar el tipo de dato de la columna mediante un ALTER TABLE por uno que sea case sensitive:
    • BINARY, VARBINARY o BLOB

Ejemplos de uso de COLLATE

mysql> SELECT nombre_usuario FROM usuarios WHERE nombre_usuario LIKE 'Al%' COLLATE latin1_spanish_cs; # retorna usuarios con nombres como 'Alberto' o 'Álvaro'. NO 'alejo'

mysql> SELECT nombre_usuario FROM usuarios WHERE nombre_usuario COLLATE latin1_bin LIKE 'al%'; # retorna usuarios con nombres como 'alejo'. NO 'Alberto' ni 'Álvaro'

 

Sabiendo también cómo cambiar el tipo de dato a un valor o a un campo, podemos notar que todas las expresiones son equivalentes cuando se utilizan en una comparación:

CAST(nombre AS BINARY) = CONVERT(nombre,BINARY) = BINARY nombre = nombre COLLATE latin1_bin

COLLATE no cambia el tipo de dato, solo aplica un collation al momento de usar el campo en una comparación