Mortuux

Diario de un estudiante geek. Informática, tecnología, programación, redes, sistemas operativos, bases de datos…

Archivos en la Categoría: Programación

Bash script que busca hosts en tu red, sincroniza carpetas y después apaga los hosts.

En clase nos pidieron hacer un script que buscase hosts en tu red para después apagarlos, o que incluso antes de apagarse sincronizasen unas carpetas.

He tratado de automatizarlo todo lo que he podido, en mi red funciona perfectamente, y el único requerimiento previo es que todos los hosts tengan instalado un servidor SSH. Este script esta pensado para hosts Linux, pero con algunos pequeños cambios se podría adaptar para Windows también.

El código es el siguiente:

#!/bin/bash

# Find online hosts on your network, backup a directory and halt them

# Copyright (C) <2011> <Adrian Espinosa>

#

# This program is free software: you can redistribute it and/or modify

# it under the terms of the GNU General Public License as published by

# the Free Software Foundation, either version 3 of the License, or

# (at your option) any later version.

#

# This program is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

# GNU General Public License for more details.

#

# You should have received a copy of the GNU General Public License

# along with this program. If not, see <http://www.gnu.org/licenses/&gt;.

# If you don’t want to write every password, you should add the hosts keys to your machine.

clear

f=`echo networkscanned_$(date +%Y%m%d)`

me=`echo $(whoami)`

DIR=”put_here_your_dir_to_sync”

DEST=”put_here_your_destination”

if [ $UID -ne 0 ]

then

echo “Sorry, you have to run this script as root”

else

net=`ip route show | grep / | cut -d ” ” -f1`

echo “Please, wait while your network is scanned”

completescan=`nmap -sP $net | grep “is up” | cut -d ” ” -f2`

clear

echo “$completescan” > $f

gateway=`ip route show | grep via | cut -d ” ” -f3`

cat $f | egrep -v `echo $gateway$` > /tmp/net

cat /tmp/net > $f

rm -rf /tmp/net

ownip=`ip route show | grep src | cut -d ” ” -f12`

cat $f | grep -v $ownip > /tmp/net

cat /tmp/net > $f

rm -rf /tmp/net

echo “Starting synchronization”

for host in $(cat $f)

do

echo “Syncing with $host”

rsync –progress -avhe ssh $me@$host:$DIR $DEST &> backup.log

ssh $me@$host “shutdown -h now” &> backup.log

done

echo “Done. You may check backup.log to see if there are any errors”

rm -rf $f

exit 0

fi # END

Hay que ser root para ejecutarlo y básicamente lo que hace es lo siguiente

  • Si NO eres root
    • Sale del programa
  • Si eres root
    • Detecta tu red y máscara
    • Escanea con nmap y recoge sólo la IP de los hosts y la guarda en fichero
    • Detecta cuál es tu ip y tu gateway y los elimina del fichero anterior
    • Recorre el fichero leyendo cada hosts y haciendo las correspondientes operaciones

.

Este script lo he probado en Debian, y como digo funciona correctamente. En ubuntu hay que hacer unos pequeños cambios que podéis encontrar en mi github, también está publicado este script.

Evitar los atributos en XML.

Algunos de los problemas de (ab)usar de los atributos en XML son:

  • Los atributos no pueden contener valores múltiples. (Los elementos sí)
  • Los atributos no pueden contener estructuras en árbol. (Los elementos sí)
  • Los atributos no se pueden extender fácilmente (para futuros cambios)

Los atributos son difíciles de leer y mantener. Para datos es mejor utilizar elementos. Usa atributos para información que no sea relevante para los datos.

dia=”10″ mes=”01″ anio=”2008″
para=”Marcos” de=”Adrian” asunto=”Recordatorio”
contenido=”No te olvides de mi cumpleaños eh :P”>
</nota>

El código anterior es complicado de leer, y ya que estamos no es para nada bonito. La forma más correcta sería:

<nota>

<fecha>

<dia>10</dia>

<mes>01</mes>

<anio>2008</anio>

</fecha>

<para>Marcos</para>

<de>Adrian</de>

<asunto>Recordatorio</asunto>

<contenido>No te olvides de mi cumpleaños eh:P</contenido>

</nota>

 

Un uso que podemos dar a los atributos en XML es para metadatos, es decir, datos sobre los datos. Por ejemplo:

<nota id=”200″>

<fecha>

<dia>10</dia>

<mes>01</mes>

<anio>2008</anio>

</fecha>

<para>Marcos</para>

<de>Adrian</de>

<asunto>Recordatorio</asunto>

<contenido>No te olvides de mi cumpleaños eh:P</contenido>

</nota>

Esta nota tiene un id “200”, y otra nota cualquiera tendrá otro id diferente, para así diferenciar las posibles notas que haya.

10 herramientas para dar más vida a tus scripts en shell

En la mayoría de nuestros scripts, no utilizamos para nada una GUI, pero a veces, si es un script que va a ir enfocado al usuario, es mejor intentar usar una GUI para que sea más amigable.

Es una tarea que a lo mejor cuesta más porque hay que dedicarle un poco más de tiempo, pero es algo que merece la pena, no todos aprecian la belleza de la consola 😀

  • Notify-send

Comando que envía notificaciones a través del daemon de notificaciones (por defecto, se muestran casi en la esquina superior derecha). Para poder utilizar ese comando, debemos instalar:

$ sudo apt-get install libnotify-bin

Después basta con un simple:

$ notify-send “texto”

Esto puede ser útil para mensajes que no tengan por qué interferir en la actividad, del usuario… por ejemplo para informarle de algo.

notify-send

notify-send

  • Comando setleds

Cambiar el estado de los leds del teclado

$ setleds -D +num

Activaría el NumLock

$ setleds -D -caps

Desactivaría el CapsLock

  • Zenity

Uno de mis favoritos. Muestra diálogos utilizando GTK+. Nos permite mostrar información, pedir datos al usuario, etc…

Zenity

Zenity

El resto de las herramientas, las podéis encontrar aquí

Enlace | nixCraft

Matrices en Php (II)

Recorrido por las matrices

El método apropiado para recorrer una matriz es utilizar la sentencia foreach(), cuya sintaxis es la siguiente:
foreach(matriz as $clave => $valor) {
... ... ...
}

El parámetro matriz representa la matriz por la que realizaremos el recorrido y $clave/$valor representan respectivamente el par individual clave/valor por el que pasamos.
$matriz = array('el', 'coche', 'es', 'azul');

/* Obtener tanto la clave como el valor */
foreach($matriz as $clave => $valor) {
echo "El valor de $clave es: $valor";
}

/*Obtener solamente el valor */
foreach($matriz as $valor) {
echo "El valor es: $valor";
}

Matrices en Php (I)

En PHP, podemos crear una variable de matriz de varias formas. La más sencilla:
$variable[expr clave] = expr;

Expr clave es una expresión que se evalúa para una cadena o cualquier entero no negativo y expr representa la expresión cuyo valor se asociará con la clave.
$var['a'] = 1;
$var['b'] = 2;
$var['c'] = 3;
$var['d'] = 4;

Si expr clave no se especifica, PHP utilizará automáticamente el siguiente entero disponible como clave.

Cuando definamos una matriz dentro de una secuencia de comandos manualmente, utilizar esta sintaxis puede ser difícil. En estos casos es mejor utilizar la sintaxis formal para las matrices; la sentencia array(). La sintaxis general es la siguiente:
$variable = array([mixto]);

En la sintaxis anterior, mixto representa los distintos pares de claves/valores definidos en este formato:
expr clave => expr valor;
expr clave => expr valor;

Por ejemplo:
$hola = array('a' => 1, 'b' => 2, 'c' => 3);
Es lo mismo que:
$hola['a'] = 1;
$hola['b'] = 2;
$hola['c'] = 3;

Matriz que asigna claves del 1 al 12 a los meses del año:
$meses = array(1=>"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");

Expresiones regulares en JavaScript

Una expresión regular es una cadena de caracteres que nos permitirá buscar coincidencias dentro de un texto o comprobar que una cadena tiene un formato concreto. En JavaScript se identifican colocando “/” al principio y al final de la cadena.

Consiste en escribir un conjunto de caracteres  para después encontrar coincidencias con él. Por ejemplo en la frase “el volante del coche” si nuestro patrón es /el/ obtendríamos que las palabras “el y “del” lo cumplen.

Para hacer más útiles los patrones, hay una serie de estructuras y caracteres especiales:

Caracteres de repetición

  • Asterisco(*): El caracter que le precede aparecerá cero o más veces.
  • Más(+): El caracter que le precede aparecerá una o más veces.
  • Interrogación(?): Igual que las opciones anteriores, pero el caracter puede aparecer ninguna o una vez.
  • {n}: Siendo n un número entero positivo, indicamos que el caracter se debe repetir al menos n veces.
  • {n,}: Similar al anterior, pero esta vez indicamos que al menos se debe repetir n veces.
  • {n, m}: El caracter debe repetirse entre n y m veces.

Caracteres especiales

  • Punto(.): Coincidirá con cualquier caracter simple excepto el salto de línea.
  • \n : Salto de línea.
  • \r : Retorno de carro.
  • \t : Caracter de tabulado.
  • \v : Tabulado vertical.
  • \f : Avance de página.
  • \uxxxx : Caracter unicode.
  • \b : Coincide con un separador de palabras.
  • \B : Coincide con un caracter que no sea separador de palabras.
  • \d : Dígito entre cero y nueve.
  • \D : Caracter que no sea un dígito.
  • \s : Coincide con un único caracter de separación.
  • \S : Coincide con un único caracter que no sea de separación.
  • \w : Coincide con cualquier caracter alfanumérico (De la “a” a la “z” en máyusculas y minúsculas, números del cero al nueve) o el subrayado.
  • \W: Coincide con cualquier caracter no alfanumérico ni subrayado.

Agrupaciones de valores

  • [xxx]: Coincide con los caracteres entre corchetes. También se puede especificar un rango contiguo de caracteres: [0-6] que esto equivale a [0123456].
  • [^xxx]: El acento circunflejo indica que coincidirán cualquier caracter salvo los especificados en los corchetes.
  • Barra vertical ( x | y ): O una cosa o la otra. Por ejemplo: /cara|cruz/, /perr[o|a]/

Modificadores

Los modificadores se colocan detras de la última barra, por ejemplo: /hola/g.

  • g : Fuerza a que se sigan buscando coincidencias después de encontrar la primera
  • i : Elimina distinción entre mayúsculas y minúsculas.
  • x : Fuerza que los espacios escritos sean ignorados.

Ejemplos útiles

  1. /\d{9}/ -> Número teléfono
  2. /\d{8}[a-zA-Z]/ -> Número DNI
  3. /\d{2}-\d{2}-\d{4} -> Fecha DD/MM/AAAA
  4. /\w+@\w+\.\w{2,3}/ -> Dirección correo electrónico.

Declaración de variables en JavaScript

Para utilizar una variable en nuestro código debe estar indicado en alguna parte de éste cuál es su nombre y/o valor. A esto se le conoce como declarar una variable.

En la mayoría de los lenguajes de programación es obligatorio declarar cada variable antes de utilizarla en el código mientras que en JavaScript se puede hacer sobre la marcha según las vayamos necesitando. Hay dos maneras de declarar variables:

  1. Declaración explícita: Consiste en usar la sentencia var seguida del nombre de la variable. Esta opción es la más recomendada, para que el código sea más legible, personalmente la recomiendo.
  2. Declaración implícita: Es cuando escribimos directamente el nombre de la variable. En este caso debe ir acompañada obligatoriamente de un valor.


// declaración explícita
var nombre;
// declaración implícita
nombre = "Paco";
// declaración explícita múltiple
var nombre, edad, apellido;
// declaración explícita múltiple con inicialización
var nombre = "paco", edad = 20, apellido = "ruiz";
// declaración implícita múltiple con inicialización
nombre = "paco", edad = 20, apellido = "ruiz";

También se pueden declarar constantes, por ejemplo el numero pi, o un valor máximo. Se declaran con la sentencia const. Pero es recomendable no usarlo porque sólo es soportado a partir del motor 1.5 de JavaScript.

Buscar y reemplazar cadenas en php

Esta tarea normalmente se realiza a través de la función strpos(cadena_donde_se_busca,subcadena_a_buscar) que devuelve false si no encuentra nada, o devuelve la posión del primer carácter buscado dentro de la cadena.

$cadena = "Hola que tal estoy probando las cadenas"
$pos = strpos($cadena, "estoy");
if (!$pos)
echo "No se ha encontrado nada\n");
else
echo "Posición: $pos\n");

Eso devolvería el valor 13.

También se puede indicar que empiece a buscar desde la derecha, para ello existe la función strrpos(). Como ya esperabas, strpos() es sensible a las mayúscualas y minúsculas, pero curiosamente no hay otra alternativa para esta función. Pero en php existe la función strstr() que funciona de manera similar a strpos() y tiene una variante sin sensibilidad a mayúsculas denominada stristr(). La diferencia entre strstr() y strpos(), es que strstr() devuelve la parte posterior de la subcadena buscada. En el ejemplo anterior, strpos() devolvía 13, pues bien, utilizando la función strstr():

$cadena = "Hola que tal estoy probando las cadenas"
$pos = strstr($cadena, "estoy");
if (!$pos)
echo "No se ha encontrado nada\n");
else
echo "Posición: $pos\n");

Eso devolvería “estoy probando las cadenas”

Para reemplazar cadenas existen dos funcionaes. Una de ellas es substr_replace, que podrá ser utilizada siempre que conozcamos la posición y la longitud de la sub cadena a reemplazar.

$cadena = "Hola que tal estoy probando las cadenas";
$nueva = substr_replace($cadena, "estoy", 13, 5);
echo "$nueva\n";

Pero no tenemos porque conocer la longitud ni la posición, para estos casos tenemos la función str_replace(subcadena_buscada, subcadena_nueva, cadena)

$cadena = "Hola que tal estoy probando las cadenas";
$nueva = str_replace("probando", "quemando", $cadena);
echo "$nueva\n";

Comparación de cadenas en php

Comparar cadenas en php no es tan fácil como hacerlo con números. Si examinamos una cadena basándonos en su forma binaria, “Juan” y “juan” serán completamente diferentes. El valor de “Juan” en binario es: 010010100111010101100001011011100000110100001010 y para “juan” es: 011010100111010101100001011011100000110100001010.

La primera función de comparación es strcmp(). El valor devuelto por esta función depende de la relación alfabética entre las dos cadenas. Si $val1 y $val2 son idénticas, strcmp() devolverá 0. strcmp() distingue entre mayúsculas y minúsculas. Si no son igualesm el valor devuelto estará determinado por las reglas de orden alfabético. Si $val1 es alfabéticamente inferior a $val2, el resultado será negativo, en caso contrario, será positivo.
echo strcmp("Alvaro", "Benito"); // Devuelve < 0

echo strcmp("manzana", "Manzana"); // Devuelve > 0

Los números tienen un valor contexual más bajo que las letras, y las letras mayúsculas un valor contextual más bajo que las minúsculas. Si queremos comparar cadenas sin distinción entre mayúsculas y minúsculas, debemos usar la función strcasecmp();

echo strcasecmp("Juan", "juan"); // devuelve 0;

Aún no existe una solución que se acerque a la capacidad del cerebro humano, pero se han desarrollado varios algoritmos que nos proporcionan un método para medir la “similitud” entre dos cadenas. Uno de estos ejemplos es el algoritmo soundex. Soundex funciona asignando un valor a cada constante del alfabeto y calculando posteriormente el valor total de una palabra basándose en sus sílabas iniciales y componentes. En php se implanta mediante la función soundex();

echo soundex("Mortuus"); //Devuelve M632
echo soundex("Mortiis"); // Devuelve M632
echo soundex("Mortem"); // Devuelve M635

Otro algoritmo para comparar dos palabras basándonos en sus representaciones fonéticas es el metáfono. Este algoritmo funciona asignando un valor fonético a combinaciones de caracteres basándose en su uso típico en inglés. Php lo implanta a través de la función metaphone();

echo metaphone("Mortuus"); // Devuelve MRTS
echo metaphone("Mortiis"); // Devuelve MRTS
echo metaphone("Mortem"); //Devuelve MRTM

Mostrar propiedades de un objeto window

Un pequeño truquillo para mostrar las propiedades de un objeto window:


<script type="text/javascript">
for (property in window)
{
document.write(property)
document.write('<br />')
}
</script>