Vim: resaltado de sintaxis

Vim es uno de los editores de texto más usados en sistemas *NIX tanto por programadores como administradores de sistemas. Tiene una curva de aprendizaje bastante inclinada, por lo que es bastante complejo para nuevos usuarios y al principio puede causar más quebraderos de cabeza que ayudar, pero una vez te haces con el funcionamiento elemental y básico del programa, puedes contar con sus potentes comandos para realizar cualquier tarea con un par de golpes de teclado.

Vim significa Vi IMproved, es decir, es un programa que nace con la intención de mejorar uno de los editores más importantes hasta el momento en UNIX: vi.

Muchas distribuciones de GNU/Linux incluyen vim entre los paquetes básicos de la instalación, otras solo vi o una versión reducida de vim. En Debian y derivadas se puede instalar la edición completa del programa con el siguiente comando:
aptitude install vim-nox

Pese a haber instalado el paquete completo, es posible que te des cuenta que sigues sin poder disfrutar del completo resaltado de sintaxis que ofrece el programa, esto es porque está desactivado en el archivo de configuración.

Para activar el resaltado de sintaxis abre como root el archivo /etc/vim/vimrc y localiza la línea que pone "syntax on y borra las comillas para descomentarla. Si no existe, simplemente añade syntax on al final del archivo.

También puedes activarlo o desactivarlo con el comando interno :syntax on o syntax off aunque esto solo se aplica en la sesión actual.

Ahora ya deberías disfrutar de esta característica tan útil. También tienes que tener en cuenta que para reconocer el tipo de resaltado a usar, vim utiliza el formato del archivo (por ejemplo, .py), la primera línea en caso de los scripts (para bash #!/bin/bash) o el nombre del archivo (.htaccess, por ejemplo).

Permitir a un usuario ejecutar un comando como root usando sudo

En otra entrada ya se trataron las diferencias entre los comandos sudo y su.

En esta entrada voy a explicar cómo configurar el archivo /etc/sudoers para permitir a un usuario determinado ejecutar uno (o varios) comandos que requieran permisos de administrador sin que tenga estos permisos en otras tareas.

Como ejemplo voy a usar el comando shutdown que sirve para apagar/reiniciar el sistema y que en la mayoría de distribuciones solo lo puede ejecutar el usuario root, aunque la aplicación es la misma para cualquier otro programa.

Antes de trabajar con el archivo /etc/sudoers estaría bien leerse su entrada del manual (man 5 sudoers) para entender mejor la sintaxis y el funcionamiento y saber qué estamos haciendo exactamente. Si no quieres, simplemente deberías conocer los siguientes datos:

  • Es un archivo muy importante y delicado y cualquier pequeño error de sintaxis puede dejarte sin permisos de administrador.
  • Para evitar sustos existe el comando visudo que abre el archivo en el editor configurado por defecto (generalmente nano) y comprueba la sintaxis antes de guardarlo, evitando así errores fatales.
  • También existe la posibilidad de no modificar directamente el archivo sino añadiendo nuevo contenido dentro del directorio /etc/sudoers.d/

Evidentemente, para editar este archivo, se necesitan permisos de administrador por lo que tienes que ingresar con la cuenta de root (su o sudo -s).

Ahora ejecuta visudo y al final del archivo (puedes añadir una línea comentada, que empiece con el carácter #, para saber donde comienzan los cambios que tu has realizado y/o explicarlos) escribe lo siguiente:
usuario ALL=NOPASSWD: comando
Cambiando usuario por el usuario que quieras y comando por la ruta completa al programa que quieres que pueda ejecutar. Para averiguar las rutas completas puede usar which comando.
NOPASSWD sirve para no requerir que el usuario introduzca su contraseña.

Ejemplo:
pi ALL=NOPASSWD: /sbin/shutdown
Permitirá al usuario pi ejecutar el comando shutdown para poder apagar mi Raspberry Pi sin tener más permisos de administrador ni introducir contraseña alguna.

Ahora el usuario en cuestión simplemente tiene que ejecutar sudo comando y podrá usar dicho comando como si fuera administrador, pero sin el peligro de que tenga más permisos de los realmente necesarios.

Servicios al inicio con rcconf

rcconf es una herramienta muy útil para controlar los servicios que se inician durante el arranque del sistema.

Probablemente ya conozcas la aplicación que suelen traer los diferentes entornos al estilo Aplicaciones al inicio, pero ahí solo se incluyen los programas que se ejecutan una vez el usuario ha iniciado sesión. En cambio rcconf muestra todos los que se ejecutan durante las fases previas del arranque, por ejemplo, el servidor gráfico y el gestor de inicio (X y mdm, gdm,…), servidores que tengas instalados, el servidor de sonido, cron,…

Es una herramienta específica de Debian y suele venir instalada por defecto en sus derivadas, aunque siempre puedes hacer uso de aptitude para conseguirla:
aptitude install rcconf

Requiere permisos de administrador, por lo que habrá que iniciar sesión como root primero. Luego lo ejecutamos:
rcconf

Como podrás observar se trata de una interfaz bastante sencilla de usar: una simple lista con algunos de los servicios, marcados aquellos que se inician al arranque y dos botones de aceptar y cancelar. La navegación se realiza con las flechas de dirección del teclado, se marcan/desmarcan las casillas con la tecla espacio y finalmente tabluador para seleccionar entre Aceptar y Cancelar e INTRO para elegir.

Hay que tener en cuenta que los cambios no son instantáneos, es decir, no cierra los procesos que desmarcas ni inicia los nuevos marcados, sino que eso ocurrirá durante el siguiente arranque.
Si quieres cerrar un servicio actualmente abierto, se suele así:
service stop
Y para iniciarlo sustituye el stop por start. O restart para reiniciarlo.

Si esto no funciona puedes buscar con ps -A el PID (el número que identificar un proceso) y matarlo con kill -9

Ficheros de texto: finales de línea

Cuando usamos un sistema diferente al que la mayoría es normal que haya veces que choquemos de golpe por incompatibilidades que nos dificultan el trabajo, por muy estúpidas que puedan parecer.

Una de ellas son los finales de línea, es decir, la forma que tienen los sistemas operativos de identificar que en un archivo hay una nueva línea cuando se trabaja con texto plano.

En ASCII (el código de caracteres latinos más básico usado en informática) existen, dentro de los caracteres de control, dos que han sido usados para marcar nuevas líneas. Estos son LF (nueva línea, generalmente representado como \n) y CF (retorno de carro o carriage return, también representado como \r). Este último es una herencia de las máquinas de escribir antiguas, teletipos y demás dispositivos mecánicos, pero que no tiene ningún sentido hoy en día pues los ordenadores ya no se ayudan de piezas móviles para procesar el texto.

El verdadero problema viene cuando los desarrolladores deciden usar diferentes implementaciones para su software, ya sean sistemas operativos, aplicaciones de cualquier tipo, protocolos de red,… ya que se está dificultando el uso tanto a usuarios como a otros desarrolladores.

El sentido común parece indicar, por lo menos desde mi punto de vista, que con el carácter de nueva línea (LF) debería valer. Y lo mismo debieron pensar los creadores de Unix y gracias a ellos es el carácter que se usa hoy en día en Unix y sistemas similares entre los que se incluye GNU/Linux.

Por el contrario, Microsoft durante el desarrollo inicial de DOS decidió mantener la convención LF + CR que se usaba en sistemas que trataban de mantener la compatibilidad con aquellos teletipos, impresoras,… que necesitaban un carácter para marcar el carriage return. Y esto es, por inercia, lo que se usa hoy en día en el sucesor de DOS: Windows.

Y, a su bola, Apple en sus SO de la familia Apple II y Mac OS 9 y anteriores, usó únicamente el carácter CR para marcar las nuevas líneas, lo cual síº que es totalmente desconcertante. Aunque a partir de Mac OS X se han unido a la convención del resto de sistemas Unix: solo LF.

Aunque no todas las aplicaciones están obligadas a seguir el estándar usado por el sistema donde se estén ejecutando, es lo común. Por ejemplo, en la mayoría de lenguajes de programación, para conseguir compatibilidad multiplataforma se ofrece una capa de abstracción en la que se establece el estándar para la nueva línea, generalmente el carácter \n y el compilador o intérprete se encarga de traducirlo al carácter de nueva línea nativo del sistema donde se está ejecutando la aplicación.

Puede que ya te hayas dado cuenta de este problema si alguna vez has abierto un documento creado en GNU/Linux con el bloc de notas de Windows y te das cuenta de que en vez de separar las líneas incluye unos símbolos (rectángulos vacíos) en su lugar. Esto puede resultar bastante tedioso si te trata de un archivo largo.

Para evitar estos problemas existen varias soluciones:

  • Usar software que identifique automáticamente el tipo de archivo. Por ejemplo, cualquier editor de textos que NO sea el bloc de notas de Windows.
  • Especificar el final de línea al guardar: Muchos editores, por ejemplo gedit, te pregunta el tipo de final de línea que se quiere usar: Unix/Linux (LF), Mac (CR) o DOS/Windos (CRLF).
  • Convertir los finales de línea: Existen comandos como dos2unix, unix2dos, mac2unix, unix2mac, mac2dos, dos2mac únicamente diseñados para realizar estas tareas.

WIFI en la Raspberry Pi

Para este artículo doy por seguro que tienes una Raspberry Pi debidamente configurada y con Raspbian instalado, aunque todo debería funcionar de la misma forma en cualquier otra distribución.

El primer paso es conseguir una tarjeta WIFI, ya que la Raspberry Pi no incluye esta característica. La única interfaz de red disponible es el puerto RJ-45 (Ethernet) del modelo B.
Hoy en día los pinchos-WIFI por USB son bastante baratos y fáciles de conseguir e incluso es posible que el fabricante incluyera uno con el router wifi. Antes de comprar uno nuevo tienes que tener en cuenta cuál es el chipset y buscar si los drivers necesarios están disponibles para Linux. Y no solo si están disponibles, sino también el nivel de compatibilidad, ya que algunos no aprovechan todo el potencial de las tarjetas wifi. Aquí tienes una lista bastante exhaustiva con todos los drivers disponibles para el kernel Linux. La wiki de aircrack-ng también tiene bastante información al respecto. Otro aspecto tener en cuenta la libertad de software, pues muchos de estos drivers son privativos.

Muchos chipsets tienen ya sus drivers incluidos en el kernel, por lo que funcionan siguiendo el modelo plug & play. Pero si ves que el sistema no lo detecta nada más enchufarlo, los siguientes pasos te pueden ayudar a encontrar los drivers necesarios.
Nada más introducir el pincho-WIFI en el sistema, abre la terminal y ejecuta:
dmesg|tail
dmesg es el log de control del kernel y tail limita la salida del mismo a las últimas 10 líneas. Deben aparecer una serie de líneas relacionadas con el último evento ocurrido, es decir, la introducción del USB. En mi caso, son las siguientes:
[12199.268244] zd1211rw 1-2:1.0: phy1
[12199.268263] usbcore: registered new interface driver zd1211rw
[12199.294189] usb 1-2: firmware: failed to load zd1211/zd1211b_ub (-2)
[12199.294192] usb 1-2: Direct firmware load failed with error -2
[12199.294193] usb 1-2: Falling back to user helper
[12199.294533] zd1211rw 1-2:1.0: couldn't load firmware. Error number -2

zd1211 es lo que me interesa (probablemente en tu caso será otro nombre diferente) ya que es el nombre del driver que necesito.
El siguiente paso es buscarlo en los repositorios (aptiutude search zd1211) e instalar el/los paquetes necesarios. Si estás usando un chipset que requiere drivers privativos para funcionar debes considerar activar los repositorios non-free o el correspondiente para tu distribución.

Otras formas de identificar la tarjeta de red puede ser usando el comando lsusb que lista todos los dispositivos conectados por USB, y posteriormente buscando en las listas de drivers cuáles son los necesarios para hacer funcionar dicho hardware.

Una vez configurado, el comando ifconfig y iwconfig deberían ser capaces de activar la interfaz de red correspondiente, normalmente wlan0.

Ahora, para que se conecte automáticamente en cada inicio, se puede usar wpa_supplicant. Para esto primero hay que configurar network manager en el archivo /etc/network/interfaces. El que trae Raspbian por defecto nos vale:

auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

La configuración de wpa_supplicant la haremos en el archivo /etc/wpa_supplicant/wpa_supplicant. Aquí escribimos lo siguiente:

network={
ssid="Nombre_de_la_Red"
scan_ssid=1
psk="contraseña"
}

Debería funcionar tanto para redes WPA, WEP o aquellas abiertas (eliminando la línea psk, aunque solo lo he podido probar en WPA.

wpa_supplicant tiene bastantes más opciones necesarias para usos más complejos. Puedes leer más en la wiki de Arch Linux o en sus entradas del manual:
man 5 wpa_supplicant.conf
man wpa_supplicant

Para aplicar la configuración basta con reiniciar el servicio wpa_supplicant, pero como no he encontrado cómo hacer esto, toca reiniciar:
sudo shutdown -r now

Mantener youtube-dl siempre actualizado

Como parece ser que la compatibilidad de youtube-dl se rompe con facilidad con muchas de las páginas de las que permite descargar vídeos y hay que actualizar manualmente cada pocos meses, los desarrolladores han incluido una nueva opción para actualizar la aplicación.

Simplemente busca la última versión disponible en la página oficial y descargarla. Pero como la aplicación suele estar en /usr/bin o similares, hay que ejecutar esta opción como root para poder completar el proceso.

La sintaxis es la siguiente:
youtube-dl --update

Si la has instalado desde los repositorios, tendrás la página del manual en tu sistema donde podrás aprender toda la funcionalidad de está aplicación:
man youtube-dl

Copiar al portapapeles desde la terminal con xclip

xclip es una herramienta que nos permite trabajar con el portapapeles del servidor gráfico (X.org). Está disponible en los repositorios de Debian y derivadas por lo que se puede instalar fácilmente con aptitude:
aptitude install xclip

El uso es muy sencillo. Por defecto toma valores del archivo que se le indique o desde la entrada estándar, es decir, la salida de otro comando redirigida por un pipe:
el_programa_que_sea | xclip

Para pegar el contenido que ha copiado puedes usar el argumento -o
xclip -o
Esto solo lo mostrará en pantalla, aunque puedes usarlo para pegarlo en un archivo con los elementos > y >>. O redirigirlo a otro programa a través de un pipe. Revisa la página de conceptos básicos para aprender más sobre esto.

Si quieres que el contenido pueda ser utilizado por otras aplicaciones, tienes que especificar el portapapeles a utilizar. En este caso -selection clipboard
xclip -selection clipboard

Entonces si, por ejemplo, quieres copiar un archivo entero y pegarlo en un procesador de textos, puedes valerte del siguiente comando:
xclip -selection clipboard archivo

O si quieres copiar la salida en pantalla del proceso de instalación de un paquete:
aptitude install paquete | xclip -selection clipboard

Este programa tiene funcionalidad más avanzada que puede comprobar desde su página del manual:
man xclip