RasPi: configuración de la red inalámbrica

En la mayoría de casos, nuestra pi detectará e instalará nuestro dispositivo wifi (normalmente un stick usb o wifi usb dongle) de manera automática, sin muchos problemas. Pero algunas veces no parece tan sencillo y simplemente lo detecta… pero la configuración base del sistema operativo no es suficiente para que quede correctamente instalado. En este caso podemos optar por dos opciones, o bien entramos en el entorno gráfico y bsucamos la configuración de conexión a redes (muy parecido a Windows) o bien lo hacemos desde la consola. Este segundo caso suele ser el mas común cuando nuestro sistema se va a dedicar a trabajar en segundo plano y no dispone de entorno gráfico (como por ejemplo, un servidor web, una estación multimedia, etc…).

Nos centramos en el segundo caso, que quizá sea el mas engorroso.

Detectar e instalar los drivers del dispositivo wifi

Lo primero que debemos hacer es comprobar que nuestra pi ha detectado el dispositivo usb correctamente. Para ello, realizamos una petición que nos muestre los dispositivos usb conectados al sistema.

Haremos uso de la órden lsusb (list usb):

pi@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter
Bus 001 Device 028: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub
Bus 001 Device 029: ID 07b5:0213 Mega World International, Ltd Thrustmaster Firestorm Digital 3 Gamepad
Bus 001 Device 030: ID 04fc:05d8 Sunplus Technology Co., Ltd Wireless keyboard/mouse

Podemos observar el listado de dispositivos usb conectados a nuestra pi. En este caso, el interesante es:

Bus 001 Device 004: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter

Se trata de un adaptador wireless con chipset RT5370 (es un mini wifi dongle usb de Conceptronics). Del mismo modo, podemos observar que el fabricante es Ralink Technology.

El siguiente paso será obtener e instalar los drivers o firmware del dispositivo, una vez conocemos su fabricante. De manera sencilla, podemos realizarlo a través de apt-get install:

pi@raspberrypi ~ $: sudo apt-get install firmware-ralink wireless-tools

Si conocemos cuál es la versión o fabricante de nuestro dispositivo, podemos hacer este último paso en primer lugar.

Configurar la conexión a la red

El siguiente paso será configurar manualmente la conexión a red. Para ello, lo primero que haremos será ver si el sistema ha detectado y conectado el dispositivo.

Mediante la órden ifconfig, comprobamos el estado de las conexiones a red:

pi@raspberrypi ~ $ ifconfig
eth0      Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:74 errors:0 dropped:0 overruns:0 frame:0
          TX packets:74 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:9360 (9.1 KiB)  TX bytes:9360 (9.1 KiB)

wlan0     Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4759 errors:0 dropped:0 overruns:0 frame:0
          TX packets:807 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 KiB)  TX bytes:0 (0.0 KiB)

El punto interesante es el dispositivo wlan0. Como observamos, está activado pero no está conectado (los parámetros RX y TX no describen actividad de datos). Ahora vamos a configurar la conexión.

Paramos el dispositivo wlan0 mediante la órden ifdown (si no está activo este paso no es necesario):

p1@raspberrypi ~ $ sudo ifdown wlan0

Ahora podemos configurar la red a la que se conectará el dispositivo wlan0 en /etc/network/interfaces

pi@raspberrypi ~ $ sudo nano /etc/network/interfaces
#; ORIGINAL
#################################################
auto lo

iface lo inet loopback
iface eth0 inet dhcp

#; auto wlan0
#; iface wlan0 inet dhcp
#; wpa-conf /opt/selector/wifiwpa.config
#################################################

auto wlan0
iface wlan0 inet dhcp
wireless-essid   SSID_NAME
wireless-channel 11
wireless-mode    managed

Observemos su contenido:

  • de la línea 1 a la 11 es el contenido original del fichero de configuración.
  • he comentado las líneas 8 a 10, ya que mi conexión, en este caso, será abierta y no precisa de configuración WPA.
  • líneas 3 y 5: configuración automática de la conexión de loopback (lo) en el arranque
  • línea 6: configuración de eth0 (ethernet) para conexión mediante dhcp
  • línea 13: conexión automática de wlan0 en el arranque
  • línea 14: configuración del dispositivo wlan0 mediante dhcp (servicio router)
  • línea 15: indicamos el nombre de nuestro SSID (endpoint del router)
  • línea 16: canal de conexión wifi (por defecto suele ser el 11)
  • línea 17: wireless mode managed (lo gestiona el router)

Esta es la configuración básica para una conexión wifi abierta (sin seguridad). Para realizar una conexión segura, deberéis comentar las líneas 13 a 17 y descomentar las 8 a 10, de modo que la configuración de SSID y contrasela wpa deberá encontrarse dentro del fichero

/opt/selector/wifiwpa.config

Para más información al respecto, podéis consultar la documentación de Debianhttp://www.debian.org/doc/manuals/debian-reference/ch05.en.html#_the_wireless_lan_interface_with_wpa_wpa2

Iniciar el servicio de conexión wifi

Ahora ya estamos en disposición de conectarnos a nuestra red a través del dispositivo wifi que hemos configurado:

pi@raspberrypi ~ $ sudo ifup wlan0

Y observamos el resultado:

Internet Systems Consortium DHCP Client 4.2.2
Copyright 2004-2011 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlan0/xx:xx:xx:xx:xx:xx
Sending on   LPF/wlan0/xx:xx:xx:xx:xx:xx
Sending on   Socket/fallback
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 6
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPOFFER from 192.168.1.1
DHCPACK from 192.168.1.1
Reloading /etc/samba/smb.conf: smbd only.
bound to 192.168.1.135 -- renewal in 110003 seconds.

Vemos que el servicio se ha iniciado correctamente, que dhcp nos ha otorgado una ip privada, la 192.168.1.135, que la puerta de enlace es la 192.168.1.1 y que la identidad se renovará dentro de 110003 segundos.

Con esto, ya estamos conectados a la red inalámbrica y, si nuestro router lo permite, a internet:

pi@raspberrypi ~ $ ping www.google.es
PING www.google.es (173.194.45.24) 56(84) bytes of data.
64 bytes from lis01s06-in-f24.1e100.net (173.194.45.24): icmp_req=1 ttl=54 time=55.8 ms
64 bytes from lis01s06-in-f24.1e100.net (173.194.45.24): icmp_req=2 ttl=54 time=60.8 ms
64 bytes from lis01s06-in-f24.1e100.net (173.194.45.24): icmp_req=3 ttl=54 time=58.8 ms
64 bytes from lis01s06-in-f24.1e100.net (173.194.45.24): icmp_req=5 ttl=54 time=317 ms
64 bytes from lis01s06-in-f24.1e100.net (173.194.45.24): icmp_req=8 ttl=54 time=276 ms
^C
--- www.google.es ping statistics ---
10 packets transmitted, 5 received, 50% packet loss, time 9024ms
rtt min/avg/max/mdev = 55.880/153.958/317.585/117.591 ms

Para cualquier comentario o pregunta, no dudéis en poneros en contacto conmigo.

Espero haberos sido de ayuda.

 

Jordi

Share Button

Related Images:

Grails: creando templates o “layouts”

No es quizá la mejor manera de empezar la sección de Grails, pero introducir el tema de los layouts (templates) es algo que encuentro muy importante, puesto que es lo primer que mas de uno queremos hacer cuando empezamos desde 0 una nueva aplicación.

Grails, como en otros muchos temas, hace muy sencillo la creación de las pantallas y vistas de nuestra aplicación a partir layouts.

Los layouts son templates, o lo que es lo mismo, plantillas. Grails utiliza plantillas para aplicar estilos y estructuras a todas las páginas de la aplicación. Aún así, si se desea, pueden obviarse.

Grails hace uso del framework de layouttering SiteMesh (podéis ver mas información de su funcionamiento y estructura en su web)

El main layout lo encontraremos en el apartado de views / layouts de nuestro proyecto: grails_app/views/layouts/main.gsp. No es mas que una página gsp (Grails Server Page) que contendrá la estructura básica de aquellas páginas a las que queramos aplicar dicho template. Veamos un caso práctico.

Para empezar, os recomiendo hacer las pruebas con un proyecto nuevo en blanco.

Creación de una página en blanco

Podéis probar a crear una página nueva (con su controlador) para poder realizar esta prueba. Yo lo que os recomiendo es empezar desde ya a editar vuestra aplicación. Por ello, lo que os propongo es editar vuestro index.gsp. De este modo, cualquier cambio que realicemos lo podremos ver rápidamente accediendo a la aplicación, sin necesidad de hacer nada mas. Si no tenéis nada qué perder, probad a hacer esto:

<html>
    <head>
        <title>Pruebas con layaouts</title>
    </head>
    <body>
        <h1>Bienvenidos!!!</h1>
    </body>
</html>

Ahora si accedéis a vuestra aplicación, veréis que el estilo es de un formato básico html. Sin mucha floritura… No es como cuando accedéis por primera vez a la aplicación después de crearla, en la que se está aplicando el estilo de Grails. Si accedéis a ver su código fuente podréis ver que es tal cuál lo que hemos editado. Sin contenidos extra en el head…

Aplicando layouts

Ahora para realizar otra prueba rápida lo que haremos es aplicarle a esta nueva página el estilo de Grails, para poder ver rápidamente cómo funciona el tinglado. El layout por defecto de una aplicación Grails nueva se llama main.gsp y podéis encontrarlo en la carpeta de layouts que os comentaba al principio: grails_app/views/layouts/main.gsp

<html>
    <head>
        <meta name="layout" content="main" />
        <title>Pruebas con layaouts</title>
    </head>
    <body>
        <h1>Bienvenidos!!!</h1>
    </body>
</html>

Hemos añadido la directiva <meta name=”layout” content=”main” /> a nuestra página (línea 3). Esto le indica a la página que debe hacer uso del layout main. Actualizad el navegador y veréis que ahora lo que ha sucedido es que hemos aplicado los estilos y contenidos por defecto de Grails.

Este es el main layout de Grails:

<!DOCTYPE html>
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"><!--<![endif]-->
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<title><g:layoutTitle default="Grails"/></title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="shortcut icon" href="${resource(dir: 'images', file: 'favicon.ico')}" type="image/x-icon">
		<link rel="apple-touch-icon" href="${resource(dir: 'images', file: 'apple-touch-icon.png')}">
		<link rel="apple-touch-icon" sizes="114x114" href="${resource(dir: 'images', file: 'apple-touch-icon-retina.png')}">
		<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}" type="text/css">
		<link rel="stylesheet" href="${resource(dir: 'css', file: 'mobile.css')}" type="text/css">
		<g:layoutHead/>
		<r:layoutResources />
	</head>
	<body>
		<div id="grailsLogo" role="banner"><a href="http://grails.org"><img src="${resource(dir: 'images', file: 'grails_logo.png')}" alt="Grails"/></a></div>
		<g:layoutBody/>
		<div class="footer" role="contentinfo"></div>
		<div id="spinner" class="spinner" style="display:none;"><g:message code="spinner.alt" default="Loading&hellip;"/></div>
		<g:javascript library="application"/>
		<r:layoutResources />
	</body>
</html>

Ahora podéis volver a consultar su código fuente. Podréis observar que se han añadido una serie de contenidos extra, tanto al head como al body. Esto es porque se ha aplicado el main layout.

Qué hay de importante aquí? Pues bastante…

  • línea 10: el título por defecto, se aplicará a todas las páginas que incluyan este layout
  • líneas de 11 a la 16: contenidos de estilos y scripts, que también serán incluidos en el head de nuestra
  • línea 17: la directiva <g:layoutHead/>. Le indica al layout que se debe incluir en este espacio el contenido head de su posible layout padre
  • línea 18<r:layoutResources />. Del mismo modo, incluimos los recursos declarados en su layout padre.
  • en la zona de body sucede lo mismo, para las directivas <g:layoutBody/><r:layoutResources />

De este modo, si aplicamos estas directivas a nuestra página podremos obtener los contenidos del layout…

Ahora, todas aquellas páginas que incluyan el main layout dispondrán de este contenido. Podemos tener tantos layouts como nos sea necesario, creándolos en la carpeta de layout, de modo que podamos aplicar a cada página un comportamiento diferente, según nos interese. Por ejemplo, mediante directivas if, decidir en función de la resolución uno u otro estilo, o la inclusión o no de ciertos scripts, etc…

Crear un layout “maestro”

Si seguimos este modo de trabajo, puede llegar a ser un poco costoso acordarse cada vez que creamos una pantalla nueva el incluir el layout que nos interesa. Si no precisamos cambiar muy a menudo de layout, podemos aplicar un layout maestro, o por defecto. Es tan sencillo como crear un layout llamado application.gsp. A partir de ahora, cualquier página que no lo indique explícitamente, extenderá dicho layout. Con esto conseguimos disponer de un layout por defecto sin necesidad de tener que incluirlo continuamente en todas nuestras pantallas.

A partir de aquí…

Es trabajo vuestro extender y crear vuestros propios layouts. Quizá si es la primera vez que lo veis, no os resulte muy interesante… pero a medida que tengáis un volumen de pantallas considerable a manejar, empezaréis a ver la importancia de los layouts.

 

Espero haber sido de ayuda.

Jordi

Share Button

Java: replaceAll y el problema del $

Recientemente he sufrido la siguiente Exception:

java.lang.IllegalArgumentException: Illegal group reference

Esta exception la obtenemos cuando intentamos hacer un String.replaceAll a un String de Java que, seguramente, contiene el caràcter especial $ (dollar sign).

Aquí el problema, que puede pasar por alto cualquier programador, es que el replaceAll de la classe String hace un replace de toda la cadena haciendose servir de expresiones regulares. Si nuestro texto original contiene el caràcter $ (carácter de final de cadena en expresiones regulares), el método String.replaceAll devuelve dicha excepción, dado que cuando encuentra este carácter, detecta final de cadena, cuando posiblemente no sea así.

Por ese motivo, lo que deberemos hacer es, si sospechamos que nuestra cadena original es susceptible de tener dicho carácter, hacerle un replace un tanto especial antes de continuar:

String originalString = "Esta es una cadena con caracteres especiales: $%&()<>";
String myString = StringUtils.replace(originalString, Matcher.quoteReplacement("$"), Matcher.quoteReplacement("//$"));
System.out.println("String original: " + originalString);
System.out.println("String modificado: " + myString);

El resultado de ejecutar el código anterior es el siguiente:

String original: Esta es una cadena con caracteres especiales: $%&()<>
String modificado: Esta es una cadena con caracteres especiales: //$%&()<>

Aquí entran en juego dos classes muy interesantes, que os paso a comentar:

  • org.springframework.util.StringUtils: package de Spring que realiza diversas tareas con Strings
  • java.util.regex.Match: creamos un matcher (con expresiones regulares) para indicar que el signo $ es un carácter especial y no un String normal

De este modo obtenemos un nuevo string, llamado myString, en el que hemos realizado un replaceAll de todos los caracteres especiales $ por //$, que es la sentencia con la que escapamos caracteres especiales en Java.

Tened muy en cuenta que si volvéis a hacer un String.replaceAll de la cadena volveréis a reproducir el error. Si tenéis que tratarla o bien consumirla, lo idoneo sería haberle aplicado la sustitución justo antes de ello.

Espero haberos ayudado!

Jordi

Share Button

Manuales SEAT 600

Hace mucho tiempo, allá por el 2002, compré un SEAT 600 L Especial. Me duró poco, pues no podía mantenerlo… No tenía manuales, ni ningún tipo de documento original. Así que lo que hice fue buscar el manual del coche por Internet. Todos los que habían eran meras fotocopias, de muy mala calidad, por cierto, y no eran demasiado visibles.

Hoy os presento 2 de los diversos manuales que por aquella época decidí reescribir en formato electrónico para que todos los aficionados al SEAT 600 pudieran disfrutarlo de manera gratuita.

Los he recuperado de la red y los subo a mi propia web (también podéis visitar mi sección de descargas):

Todo aquello quedó a medias. Empecé a editar el del L Especial, pero me hacía falta muchas imagenes. También comencé el de Taller y Mantenimiento, pero eran demasiadas páginas. Desgraciadamente ahora ya no sé dónde se encuentran todos los archivos originales. Quizá algún día pueda volver a presentar novedades al respecto.

Por otro lado, creo que este post merece que nombre a alguien muy especial para mí en todo esto del 600. Mi gran amigo Emilio Borredà, a quien siempre recordaré por las tantas cosas y momentos que compartimos en la distancia.

Me gustaría que bajo ningún concepto se vendieran o que alguien pudiera hacer negocio con ellos, ya que la principal finalidad es que estos manuales lleguen de forma gratuita a todos aquellos aficionados que no puedan disponer de un manual original para disfrutar con su 600.

Compartidlos, y espero que os sean de gran ayuda!

Jordi

Share Button

Serie de artículos RasPi

Con este lema empiezo una zona de mi blog dedicada a andar tus primeros pasos con tu RasPi.

Y para ello, qué mejor que visitar mi primer artículo, RasPi: Empieza aquí (I), un primer artículo en el que te informo cómo y dónde comprar tu RasPi y todos los perfiréricos mínimos necesarios para ponerla en funcionamiento.

En una próxima entrega veremos cómo preparar la SD con la última distribución Raspbian y el posterior acceso al sistema operativo una vez instalado.

Espero que os sea de gran ayuda. No dudéis en dejar vuestros comentarios!

Jordi

Share Button

RasPi: GPIO Cheat Sheet

Por cortesía de Pimoroni, os dejo el enlace a la Cheat Sheet del GPIO de la Raspberry Pi.

Muy interesante, ciértamente…

http://pimoroni.com/swag/pi/raspberry-pi-gpio-cheatsheet.pdf

Share Button

Oracle: Identificar el encoding de la base de datos

Normalmente siempre se hace uso de un único encoding para toda una aplicación web, tanto a nivel de vistas (ya sea hatml, jsp, asp…) como de comunicaciones (conexiones a base de datos,s ervicios distribuidos, servicios web, etc…). Este encoding acostumbra a ser el estandard UTF-8, aunque también se utiliza (demasiado para mi gusto) el conocido ISO-8859 de Windows. No voy a entrar en detalles de por qué uno es mejor que el otro, para eso mejor consultáis el enlace que os dejo aquí, hacia la Wikipedia: Character Encoding.

Pero a menudo sucede que o la base de datos o alguno de los servicios que consumimos no son propios nuestros, sino que estan mantenidos por terceras empresas. En ese caso, cabe la posibilidad de que lo que os suceda es que, al presentar por pantalla en texto plano, código o contenidos leidos directamente desde la base de datos, éstos se vean incorrectamente, con carácteres “raros”, etc…

En ese caso, lo que podemos hacer es comprobar qué encoding usamos en base de datos.

Si tenemos una Oracle, podemos hacerlo de diversas maneras distintas, pero quizá esta sea la mas sencilla, ya que no sólo nos presenta esa información:

SELECT * FROM NLS_DATABASE_PARAMETERS

Como resultado, deberíamos obtener algo del estilo (es un listado de propiedades):

NLS_CHARACTERSET : UTF8

En vuestro caso, cualquiera que sea su valor (ISO, UTF16, etc…), como véis para mi, UTF-8.

Ahora ya podéis comprobar el encoding de vuestra base de datos, a parte de algunas cosillas mas…

Espero que os haya sido de ayuda.

Share Button

Forzar la descarga de ficheros desde PHP

Recientemente me han pedido que añada en una de las webs que administro un enlace (de manera artesanal) para poder descargar un documento concreto.

Bien… la mayoría pensaréis que es algo trivial, porque seguramente uso alguno de los múltiples cms que existen en el mercado (y no os equivocáis), que seguro implementa de core o mediante algún sencillo plugin… Y es totalmente cierto. Pero, como os planteaba en la primera línea, me lo han pedido de forma “artesanal”.

En fin, no le demos mas vueltas, porque no tiene mucho sentido.

Sin más preámbulos, os dejo un código escrito en php que hará las delicias de los mas necesitados.

<?php
    // accepted file extensions
    $extensions = array("pdf","mp3","zip","rar");

    // file name to download
    $file = $_GET["file"];

    // file size
    $size = filesize($file);

    // Prevent go throught directories
    if(strpos($file,"/")!==false){
        die("Permission denied to change directory, please, especify only a file name");
    }

    // test the file estension
    $ftmp = explode(".",$file);
    $fExt = strtolower($ftmp[count($ftmp)-1]);
    if(!in_array($fExt,$extensions)){
        die("ERROR: File extension not recognized: $fExt");
    }

    // if it was ok, let's download it
    header("Content-Transfer-Encoding: binary");    
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=$file");
    header("Content-Length: $size");
    $fp=fopen("$file", "r");
    fpassthru($fp);
?>

Expliquemos un poco las líneas mas importantes

  • 3 : definimos un array de extensiones de fichero aceptadas (en este caso, pdf, mp3, zip, rar…)
  • 6 : obtenemos de la request (query string) el nombre del fichero a descargar, mediante el parámetro file
  • 9 : validamos el parámetro, y no permitimos que se especifiquen nombres de fichero que contengan cambios de directorio, para prevenir descargas no deseadas (si encontramos una / terminamos con un error)
  • 14 : extraemos la extensión del fichero solicitado
  • 15 : eliminamos el . de la extensión y lo convertimos a minúsculas, para asemejarlo al array de aceptados
  • 16 : comprobamos que la extensión existe en el array de extensiones aceptadas, y en caso contrario, finalizamos con un mensaje de error adecuado
  • 21 : modificamos la cabecera de respuesta html para indicar que contiene un binario
  • 22 : añadimos a la cabecera html el nombre del fichero a descargar
  • 23 : abrimos el fichero como lectura (aquí es donde podemos comprobar que el fichero debe estar en la ruta actual en la que se encuentra esta misma página php, aunque si deseais cambiar el directorio de almacenamiento de los ficheros, es tan fácil como añadir la ruta delante del $file
  • 24 : se escribe el fichero en la response de la página

Como véis, el procedimiento es muy sencillo:

  • Subid vuestro fichero al directorio desde dónde descargaréis los ficheros
  • Subid vuestro código al directorio desde dónde descargaréis los ficheros (este es el caso sencillo, pero como os he explicado sobre la línea 23, la ruta podría variarse sin problemas)
  • Añadid un link a vuestra imagen o texto de descarga, (supongamos que yo tengo el tinglado montado en /files)  del tipo: /files/download.php?file=nombre_fichero

Y ya lo tenéis.

Fácil, ¿verdad?

Espero haberos sido de ayuda!

Jordi

Share Button

Nueva sección de fotografías: Lugares abandonados

Buenas noches,

Acabo de publicar una nueva página dentro de mi sección de fotografía: Lugares abandonados.

Y para inaugurarla, os dejo una pequeña selección de fotos de la Torre Salvana, un pequeño castillo, con mucha historia, ubicado en la Colonia Güell, en Santa Coloma de Cervelló (Baix Llobregat, Barcelona).

Espero que la encontréis interesante.

Jordi

Share Button

REISUB, cómo reiniciar tu Linux de forma “amistosa”

Seguramente, aquellos que trabajáis a menudo con Linux, os habéis quedado en alguna ocasión a medias con algún trabajo, cuando el pc, sin explicación alguna, se cuelga. A mi me solía pasar bastante en el pc del trabajo cuando se activaba el protector de pantalla…

Pues bien, entre otras, existe una secuencia de teclas, o llamada a sistema, que nos puede ayudar con este tedioso problema. Bueno, al menos, en algunas ocasiones.

La secuencia de teclas, REISUB (algunos la llaman, REIniciate SUBnormal…) es la encargada de indicarle al sistema operativo una serie de comandos que debe realizar para que se apague y se reinicie de una manera amistosa o graciosa (en Inglés, gracefully).

Para llevarla a cabo, debemos apretar las siguientes teclas en este orden, y sin soltar las dos primeras:

AltImpr Pant R E I S U B

¿Qué significa cada letra?

  • R : otorga al teclado el control del sistema (Raw)
  • E : manda un sign term a todos los procesos para que finalicen de forma amistosa (End)
  • I : indica a los procesos que deben finalizar de manera  inmediata, sign kill (Inmediate)
  • S : sincroniza el sistema de ficheros para que no se pierda información al apagar (Sync)
  • U : desmonta el sistema de ficheros y todas las unidades y discos duros (Umount)
  • B : reinicia el sistema (reBoot). También podemos hacer uso de la tecla O, para indicar que se apague en vez de reiniciarse (Off)

Esta secuencia debe realizarse de manera seguida, sin pausa. Tras ello, el sistema debería reaccionar, apagándose o reiniciandose de manera controlada, por lo que al volver a arrancar habremos corrido menos riesgos de pérdida de datos.

Espero haberos ayudado!

Jordi

Share Button