Linux: script para crear usuarios automáticamente con contraseñas aleatorias desde una lista dada en CSV.

Vamos con un script para automatizar tareas. Tenemos un CSV, le llamaremos user.csv, con los siguientes datos: Nombre, Primer Apellido y Usuario. Algo tal que así

Manuel,Garcia,ManuG1
Pedro,Rodriguez,PredroR2
Maria,Abalo,MariaA45
Josefa,Perez,JosefP21
Marta,Rios,MartaR91

La idea del script es la siguiente: recorre el fichero csv y crea a los usuarios con ese nombre y apellido y ese código de usuario. Asigna una contraseña generada de forma aleatoria y redirige la salida a un fichero para poder notificar a los usuarios creados su usuario y contraseña.

#!/bin/bash

OLDIFS=$IFS
IFS=","

while read firstname lastname userid 
do 
     PS=$(openssl rand -base64 12)   
     useradd -c "${firstname} ${lastname}" -p $PS -d /home/"${userid}" -s /bin/bash "${userid}"            
     echo "Usuario: ${userid} - Contraseña: $PS ....." >> resultado.txt 
done < user.csv

La opción de crear los usuarios con contraseña no es recomendable en todos los ámbitos por temas de seguridad, lo he hecho en este caso porque el ejemplo real en el que lo hice lo había requerido así el cliente, pero según la política y el contexto de seguridad no es algo recomendable en todos los casos porque podrían ser vistas por algún usuario no autorizado, así que aunque la generes así es mejor obligar a los usuarios a cambiarla. Para crearlo sin contraseña en la instrucción useradd quita el parámetro -p $PS, la línea de encima que genera el password (que ya sería inútil) y el $PS en la salida.

Anuncios

Trabajar con porcentajes en SQL-Server: evitar conversión a entero.

Me animo a hacer esta entrada porque habla sobre algo simple pero que por un detalle me rompió la cabeza.

Vamos con el caso/ejemplo, tenemos una tabla Precios con tres columnas: descripción, precio y descuento. La primera es de tipo varchar, la segunda del tipo money y la tercera del tipo numeric, ya que almacena el porcentaje que descontamos sobre el precio. En la consulta queremos sacar esos tres campos y un cuarto campo calculado, el importe con el descuento aplicado. Parece que bastaría con una consulta así:

Select 
  Descripcion,
  Precio,
  Descuento
  Precio * (1-Descuento/100) as ImporteConDescuento
from
  Precios

Y ya estaría, ya tenemos nuestro importe con descuento… Pero ejecutas la consulta y ves algo raro ¿los decimales? ¿dónde están? Se está redondeando el cálculo para que devuelva un valor entero. ¿Por qué? Porque al haber operado con dos enteros en el cálculo del porcentaje el motor que realiza la consulta ha convertido el resultado a entero. Sí, así es, si operas con enteros hace una conversión a ese tipo (al menos SQL-Server 2008). Para obtener el resultado correcto tendrías que hacer así la consulta:

Select 
  Descripcion,
  Precio,
  Descuento
  Precio * (1.00-Descuento/100.00) as ImporteConDescuento
from
  Precios

Así que acuérdate de los tipos cuando uses una constante en una operación: si el resultado tiene que ser decimal usa decimales.

Obtener edad desde una fecha en Javascript

Hace un tiempo habíamos visto cómo obtener una edad desde una fecha de nacimiento en PostgreSQL, en MySQL y en MS SQL-Server. ¿Y en javascript? Vamos a ver tres funciones:

En la primera función el parámetro que recibiremos será una cadena con una fecha en formato YYYYMMDD (por ejemplo 20180211 para hoy):

function terIdade(cadeaData) {
    var hoxe = new Date();
    var nacemento = new Date(cadeaData);
    var idade = hoxe.getFullYear() - nacemento.getFullYear();
    var m = hoxe.getMonth() - nacemento.getMonth();
    if (m < 0 || (m === 0 && hoxe.getDate() < nacemento.getDate())) {
        idade--;
    }
    return idade;
}

Otra opción, pasando el mismo parámetro, es conseguir el resultado el milisengundos y operar con él para obtener la edad. Para eso dividiremos la diferencia entre fechas entre 1000*60*60*24*365.25:

function terIdade(cadeaData) {
    var nacemento = new Date(cadeaData);
    var data = new Date();
    var dif = data-birthdate;
    var idade = Math.floor(dif/31536000000);
    return idade;
}

La tercera opción sería no mandar a la función una cadena con la fecha, sino separados el año, el mes y el día (pasándoselos como enteros, no como cadenas). Y para el resto haríamos más o menos la misma operación que en el ejemplo.

function terIdade(ano,mes,dia) {
    var hoxe = new Date();   
    var idade = hoxe.getFullYear() - ano;
    var m = hoxe.getMonth() - mes;
    if (m < 0 || (m === 0 && hoxe.getDate() < dia)) {
        idade--;
    }
    return idade;
}

Hacer que un fichero en Linux no pueda ser borrado ni modificado.

A veces nos interesa que en nuestro sistema Linux haya algún fichero inmutable, que no pueda ser borrado o modificado incluso aunque se intente con permisos de superusuario. ¿Es posible? Sí, con el comando chattr y usando la opción +i. Por ejemplo:

chattr +i nombre_del_fichero

Si lo aplicamos a una carpeta esto haría no solo que la carpeta no pueda ser borrado o editada sino que tampoco se puedan añadir nuevos ficheros a la misma o borrarlos, pero sí se podrían editar estos ficheros. ¿Se puede hacer que estos tampoco puedan ser editados? Sí, habría que aplicar el comando de forma recursiva sobre la carpeta para que afecte a todo lo que esta contiene:

chattr +i -RV nombre_de_carpeta

¿Y para quitar este flag y poder borrarlo o editarlo? En lugar de +i se usa -i:

chattr -i nombre_del_fichero

¿Esto tiene alguna utilidad? Pues sí. Por ejemplo podéis hacer que el fichero de usuarios o de contraseñas del sistema sea inmutable, de forma que nadie podría darse de alta sin antes modificar los permisos del fichero para ello, dando un punto extra a la seguridad.

Recursividad en Javascript

Ya hace años hablábamos por aquí sobre la recursividad con ejemplos para C y C++. Es un buen momento para hacer otra entrada, pero ejemplificada en Javascript.

Pero antes de los ejemplos refresquemos la memoria ¿Qué es la recursividad? Se trata de un potente (y a veces peligroso) recurso en la programación. Como aquella primera vez os dejo la definición de la wikipedia:

“…la forma en la cual se especifica un proceso basado en su propia definición.”

“Un problema que pueda ser definido en función de su tamaño, sea este N, pueda ser dividido en instancias más pequeñas (< N) del mismo problema y se conozca la solución explícita a las instancias más simples, lo que se conoce como casos base, se puede aplicar inducción sobre las llamadas más pequeñas y suponer que estas quedan resueltas."

Esto dicho así puede sonar confuso o denso, por lo que podríamos resumirlo como que es una técnica de programación donde una función se llama a si misma.

En la publicación original os ponía dos ejemplos en C, aquí nos vamos a quedar solo con uno para javascript ¿Cómo se calcula el factorial de un número? La operación es la siguiente:

function factorial(num)
{
    // No acepta menores que cero.
    if (num < 0) {
        return 0;
    }
    // Si recibe 0 entonces devuelve 1.
    else if (num == 0) {
        return 1;
    }
    // Si es mayor que cero se llama a si misma.
    else {
        return (num * factorial(num - 1));
    }
}

Libre Office 6 ya está disponible

Viene cargadito de cambios LibreOffice 6. Ayer, 31 de enero de 2018, The Document Foundation liberó la última versión de la conocida suite ofimática libre para sistemas operativos Windows, MacOS y Linux.

Si tenéis una manzanita necesitaréis al menos la versión 10.9 del sistema operativo instalada en vuestro equipo. En caso de usuarios de Windows ya no hay soporte en esta versión para Windows XP o para Vista, siendo Windows 7 SP1 el sistema operativo mínimo requerido. En el caso de Linux os puedo dar una lista de requisitos más detallada:

  • Kernel 2.6.18 o superior.
  • glibc2 versión 2.5 o superior.
  • gtk versión 2.10.4 o superior.
  • 256 MB de RAM como mínimo.
  • Al menos 1.55 gigas de espacio en disco duro.
  • Entorno de escritorio (GNOME o KDE).

Entre las múltiples novedades, aparte de la interfaz y de las mejoras en la integración de LibreOffice Online (la versión cloud de LibreOffice), encontramos nuevas plantillas para Impress, nuevas tipografías, mejoras en el corrector gramatical, nuevos estilos para tablas y formularios en Writer, la posibilidad de exportar directamente a ePUB los documentos o la posibilidad de firmarlos con OpenPGP.

Ya puedes descargarlo desde la página del proyecto.

Funciones lógicas en las hojas de cálculo de Google Drive

Hace unos años habláramos aquí de funciones lógicas en LibreOffice. En aquel entonces ya existía Google Drive pero no conocía a mucha gente que lo utilizara para sus labores ofimáticas. Hoy por hoy su uso se ha popularizado bastante, así que mi idea es repetir la misma entrada, pero con las funciones lógicas de esta hoja de cálculo que, más o menos, son similares (aunque en caso del Drive son menos que en LibreOffice, se quedan en 7). Lo primero que veremos, la lista de funciones:

  • FALSO: Una función que no evalúa ningún dato, sólo devuelve el valor lógico false.
  • VERDADERO: Una función que no evalúa ningún dato, sólo devuelve el valor lógico true.
  • NO: Recibe una expresión lógica, su sintaxis sería NO(La_Expresión_Lógica) y devuelve el valor contrario al que recibe. Es decir, si la expresión que recibe es true la función devolverá false y viceversa.
  • SI: Esta función requiere tres parámetros que son una prueba lógica, un valor a devolver si se cumple y un valor a devolver si no, aunque sólo es obligatoria la prueba lógica. Más abajo os explicaré como anidar varios. La sintaxis básica es SI(prueba lógica; valor si se cumple; valor si no).
  • SI.ERROR: Función que recibe dos parámetros. Devuelve el valor del primero si este no es erróneo, en caso de que lo sea devuelve el segundo. La sintaxis es SI.ERROR(valor_a_evaluar,valor_si_error)
  • O: La función recibe varios argumentos y devuelve true en caso de que alguno sea verdadero, en caso de todos sean falsos devuelve false. La sintaxis es O(expresión1,expresión2,expresión3)
  • Y: La función recibe un número variable de argumentos. En caso de que todos sean verdaderos devuelve true y caso de que alguno sea false devuelve false. La sintaxis es Y(expresión1,expresión2,expresión3)

Ahora vamos con un ejemplo. Primero tenemos estos datos con nombres de usuarios, su ciudad y su edad. En base a la edad y la ciudad calcularemos un importe que tienen que pagar usando algunas de estas funciones lógicas. Las condiciones son las siguientes: si son de Madrid y mayores de 28 entonces pagan 100. Si son de Vigo, de Basauri o tienen más de 50 años entonces pagan 50. El resto pagan 200.

Ejemplo Drive Hoja Calculo 1

La función sería la siguiente:

=SI(Y(C2=“Madrid”;B2>28);100;SI(O(C2=“Vigo”;C2=“Basauri”;B2>50);50;200))

Aunque una vez la escribáis os la traducirá a la nomenclartura inglesa de las funciones:

=IF(AND(C3=“Madrid”;B3>28);100;IF(OR(C3=“Vigo”;C3=“Basauri”;B3>50);50;200))

Y el resultado de esos datos sería el siguiente:

Ejemplo con los datos calculados