Solución al error E_FAIL(0x80004005) de Virtual Box

Hoy me encontraba con un problema con VirtualBox, en un equipo no me arrancaba ninguna máquina. Daba igual que fuera una máquina importada desde otro ordenador que que se tratara de una máquina creada desde 0. Al ejecutarla saltaba el error E_FAIL(0x80004005) . Intenté ojear los logs para ver si veía algo claro, pero el tamaño del mismo no lo hacía muy práctico ¿por qué fallaba? Pues no tengo ni idea. ¿Solución? Encontré varias:

Encontré un blog donde se afirma que se arregla desmontando la unidad de cd, pero no me funcionó tras hacerlo.

Encontré otro enlace donde decían que bastaba con ir a C:\Users\COMPUTER_NAME\.VirtualBox\Machines\VM_NAME y allí buscar el archivo VM_NAME.xml-prev para editar su nombre y quitarle el sufijo -prev. Lo probé pero tampoco funcionó.

Finalmente este vídeo me trajo la solución: en lugar de pulsar en la flecha inicio para arrancar la máquina hay que darle al botón que tiene al lado para desplegar el menú y allí elegir Inicio Desacoplable.

¿Por qué funcionó esta y el resto no? Bueno, a estas alturas no conozco todavía la causa del error, pero mirando con detenimiento el mensaje de error veo que en la solución que me funcionó el fallo era en el componente Machine Wrap. Asumo que el código de error puede ser el mismo para diversos componentes y que cada uno tiene una solución. Fíjate en el ejemplo que viene en el blog donde recomiendan desmontar la unidad de cd, podrás ver que el componente que falla simplemente es descrito como Machine mientras que en el que implica modificar el nombre del fichero de configuración xml el fallo era en el componente VirtualBox. Por tanto no hay una única solución a este error, todo depende de qué componente sea el afectado.

Declarar una función en Javascript

Hemos hablado mucho de javascript en este blog, pero a veces nos dejamos por explicar cosas básicas ¿Cómo se declara una función? y ya puestos ¿para qué sirve hacerlo?

Bueno, la utilidad de una función es no tener que repetir el mismo bloque de código varias veces. Nos permite agrupar externamente una serie de instrucciones para luego llamarla desde cualquier parte del código.

Para declarar una función debemos usar la palabra reservada function. Tras ella, separada por un espacio, ponemos el nombre que queremos darle seguido de los párametros que recibirá ,si es que recibe alguno, que pondremos entre paréntesis. Abriremos unas llaves y dentro insertaremos el código de la función. Si la función debe devolver un valor esto lo definiremos con la palabra return, que además finalizará la función. Vamos con un ejemplo práctico, una función que calcula un precio final aplicándole unos valores fijos al que recibe:

function precioFinal(precio,descuento){
  var ivaCultural = 1.21;
  var gastosEnvio = 10;
  var precioFinal = (precio*ivaCultural*(100-descuento/100))+10;
  return precioFinal.toFixed(2);
}

La función recibiría un precio y un descuento en porcentaje, le añadiría el IVA, le aplicaría el descuento, le sumaria los gastos de envío y devolvería el resultado rendondeado a dos decimales. En el código llamaríamos así a la función:

var precio = precioFinal(449.99,10);

Como el intérprete de javascript de los navegadores busca en primer lugar la declaración de variables y de funciones una función puede aparecer en el código antes de ser declarada.

SQL Server: Obtener la primera o la última palabra de una cadena.

El caso: tenemos una cadena de caracteres en SQL-Server (2008 R2 para más señas), donde las palabras están separadas por un caracter concreto. ¿Cómo obtenemos la primera palabra mediante una consulta? ¿Y la última?

La primera es fácil, sólo tenemos que hacer un SUBSTRING() que llegue hasta la primera aparición del caracter separador, que en este caso es un espacio:

DECLARE @test NVARCHAR(255)
SET @test = 'Esto es una frase'
Select SUBSTRING(@test, 1, CHARINDEX(' ', @test, 1) - 1)

¿Y la última? La cosa se torna compleja en SQL-Server 2008 (no se si en versiones posteriores es más sencillo). Y es que tenemos CHARINDEX(), que nos localiza la primera aparición del caracter empezando a contar desde una posición fija, pero no algo similar a LASTINDEX que nos diga la última posición. Entonces ¿cómo vamos a sacar esta última palabra? Pues sirviéndonos de la función REVERSE() para poder encontrar la última aparición del espacio a base de darle la vuelta a la cadena:

DECLARE @test NVARCHAR(255)
SET @test = 'Esto es una frase'
SELECT REVERSE(LEFT(REVERSE(@test), CHARINDEX(' ', REVERSE(@test))-1 ))

Usando el comando find para encontrar varias extensiones de archivo en Linux

Vamos con una entradilla sobre comandos en Linux para celebrar que hoy Microsoft se ha unido a la Linux Foundation. Sabemos que con el comando find seguido de una cadena de caracteres podemos encontrar todos los ficheros con esa extensión dentro de un directorio, veamos cómo sería la sintaxis más simplificada:

# find *.zip

La instrucción de arriba nos mostraría todos los ficheros cuyo nombre termine en .zip que estén situados en la carpeta en la que nos encontremos.

Ok, ¿y si quiero buscar varias extensiones?. Veamos ¿cómo sería el comando para buscar tanto los zip como los txt?

# find . -type f \( -name "*.zip" -o -name "*.txt" \)

Aquí ya tenemos una sintaxis un pelín más compleja, expliquemos paso a paso todo:

El . indica que queremos buscar en el directorio actual. Con -type f decimos que queremos buscar por tipo de fichero y que queremos archivos simples, no carpetas u ocultos. Entre paréntesis metemos la condición de lo que queremos buscar: con el -name indicamos que queremos buscar un patrón, que lo definimos a continuación entre comillas (el «*.zip» y el «*.txt», que vendrían a decir que queremos todo lo que acabe en esas extensiones) y el -o nos serviría como un operador lógico or. Si te fijas antes de cada paréntesis se ha introducido el carácter de escape \ para evitar posibles problemas de sintaxis.

Es decir, toda la clave es usar el -o para añadir más condiciones a la función de búsqueda, pudiendo así definir varios patrones.

PHP: ¿Cómo saber si una variable existe?

Situación clásica en PHP: En una página tengo que mostar tal o cual resultado si una variable tiene un valor concreto, pero además existe la posibilidad de que dicha variable no exista. ¿Cómo evito que me salte un mensaje de error si esta viene vacía? Pues usando el método isset().

Un ejemplo

if (isset($_GET["id"])){
     //carga los datos asociados al id
}else{
     //no carga nada
}

Ya hace tiempo explicamos aquí la diferencia entre isset(), is_null() y empty().

Cerrar un terminal en Linux sin matar el proceso en ejecución

La idea es clara: ejecutamos un comando en segundo plano y queremos cerrar el terminal pero no matar el proceso ¿cómo lo hacemos?

Pongamos un ejemplo: queremos ejecutar rsync para copiar un volumen grande de ficheros de una carpeta a otra y queremos luego poder cerrar el terminal sin que se corte el proceso.

Lo primero es lanzar en segundo plano el rsync, para ello lo ejecutaremos añadiendo la instrucción & al final, que lo envía directamente a segundo plano (también se podría hacer con el comando bg, pero con & es más directo)

$ sudo rsync home/music/* usr/otro/home/music/ &

Y vamos con lo siguiente ¿cómo disociamos este proceso del terminal para poder cerrarlo? Pues basta con ejecutar disown

$ disown

Este comando básicamente lo que hace es impedir que el terminal envíe una orden de finalización al proceso cuando se cierra.

Otra opción es utilizar nohup, que ya lo ejecutaría disociado del terminal:

$ sudo nohup rsync home/music/* usr/otro/home/music/ &

Añadiendo una capa extra de seguridad al login de PHPMyAdmin

He visto este artículo en Tecmint esta semana y he pensado que no estaría de más comentarlo por aquí, por aquello de que muchos de los que llegáis a este blog es porque buscáis una solución que no esté en inglés sino en castellano.

En fin, la idea es poner protección con contraseña a la propia página de login de PHPMyAdmin, esto nos obliga a poner dos contraseñas para entrar en lugar de una. Puede paracer paranoico, pero recuerda que es el corazón y el cerebro de vuestro servidor web. Como es habitual nos centraremos en la versión para Debian/Ubuntu. Los ejemplos los copio y pego del artículo original.

Bueno, lo primero es añadir estas líneas al fichero /etc/apache2/sites-available/000-default.conf

<Directory /usr/share/phpmyadmin>
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>

Lo siguiente será usar htpasswd para generar un fichero de contraseña para una cuenta que tendrá el acceso autorizado a la página de login. Usaremos el parámetro -c para que cree la cuente o, en caso de que exista, se la cargue y genere una nueva. En el ejemplo usan tecmint como  usuario, así que copio tal cual:

# htpasswd -c /etc/apache2/.htpasswd tecmint

Tras eso nos pedirá que insertemos la nueva contraseña dos veces. El siguiente paso nos lleva  a modificar los permisos sobre el fichero para que ningún usuario indeseado pueda leerlo:

# chmod 640 /etc/apache2/.htpasswd
# chgrp www-data /etc/apache2/.htpasswd

De esta forma si intentamos acceder a nuestro PHPMyAdmin nos encontraremos con lo comentado: nos pide una contraseña para poder acceder al login, donde tendremos que meter otra para entrar. Como recomendación, para que esto sea útil no uséis el mismo usuario y contraseña para las dos.

Subida múltiple de archivos con HTML5 y PHP

Llevaba tiempo sin tocar el PHP, sumergido en el lado del mal (aka ASP y otras cosas de Microsoft), pero el otro día tuve que retomarlo. El PHP es como ese amigo de toda la vida que por vicisitudes laborales ahora sólo puedes ver una vez cada varios meses, pero con el que te sientas en la barra de un bar y parece que todavía os visteis ayer.

El caso es que tenía que modificar un formulario para que permitiera implementar una subida de múltiples archivos. ¿Cómo va esto? Bueno, vamos con el marcado HTML:

<form action="index.php" method="post" enctype="multipart/form-data">
  <input name="upload[]" type="file" multiple="multiple" />
</form>

Puntos importantes: el enctype=»multipart/form-data» en la etiqueta form para que este envíe correctamente los archivos que subimos, el definir el nombre del input como un array poniendo los corchetes [] y la etiqueta multiple=»multiple» que nos permitirá seleccionar varios items a las vez.

Vamos ahora con el PHP con explicación línea a línea:


// RECORREMOS LOS FICHEROS
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
  //Obtenemos la ruta temporal del fichero
  $fichTemporal = $_FILES['upload']['tmp_name'][$i];

  //Si tenemos fichero procedemos
  if ($fichTemporal != ""){
    //Definimos una ruta definitiva para guardarlo
    $destino = "./nuestraCarpeta/" . $_FILES['upload']['name'][$i];

    //Movemos a la ruta final
    if(move_uploaded_file($fichTemporal, $destino)) {
       //imprimimos el nombre del archivo subido
       printf("Se ha subido el fichero %s.",$_FILES['upload']['name'][$i]);
    }
  }
}

Javascript: mostrar número con decimales en formato de moneda.

Seguro que más de una vez has estado trabajando con Javascript y has necesitado calcular un importe monetario. Y seguro que más de una vez a aplicar un descuento porcentual te ha salido un churro con 7 decimales (aprox) ¿Cómo se puede solucionar esto? pues con el método toFixed().

El método toFixed() existe de Javascript 1.5, se puede aplicar sobre todos los objetos numéricos y devuelve una cadena con el número seguido de tantos decimales como le pasemos a la función como parámetro. Si la cantidad de decimales que queremos es menor que la del número al que aplicamos el método realizará una operación de redondeo, en caso de que sea mayor entonces rellenará con ceros. Si no le pasamos ningún número como parámetro entonces redondeará a entero.

var n = 5.56998767123;
var num1 = n.toFixed();
var num2 = n.toFixed(3);
var num3 = n.toFixed(2);

//num1 tendrá el valor 6
//num2 tendrá el valor 5.570
//num3 tendrá el valor 5.57

Por tanto, si necesitas un formato monetario te basta con un .toFixed(2) para mostrar sólo dos decimales.

Copiar ficheros a una carpeta propiedad de root en el entorno gráfico de Ubuntu o Elementary OS

El título es largo, sí, pero era lo que quería intentar en mi equipo: copiar unos ficheros de la carpeta Home a la carpeta /usr/share/games. Ok, podría hacerlo por línea de comandos, pero entonces no estaría escribiendo aquí. ¿Se puede hacer desde el entorno gráfico? Pues sí. Pulsas Alt+F2 para abrir el lanzador y allí tecleas gksu nautilus. Tan simple como eso, lanzas gksu nautilus, te pedirá contraseña, y tras insertarla ya puedes crear, mover o borrar ficheros de ahí en el entorno gráfico. Como siempre en estos casos hazlo con precaución, no borres lo que no debes.