24/4/09

Mantener acentos y eñes al montar FAT, NTFS, SMBFS y al compartir directorios con Samba

En el pasado a menudo he tenido problemas con los acentos y las eñes al montar particiones FAT o NTFS o al montar o compartir directorios usando Samba. Esto ocurre porque GNU/Linux usa distintos juegos de caracteres que Windows y DOS.
En esta entrada vamos a tratar de aclarar todos los aspectos que pueden impedirnos disfrutar de nuestra apreciadas eñes cuando nos enfrentamos con ficheros cuyo origen o destino sea un sistema operativo de Microsoft.

Existe una multitud de juegos de caracteres. Podemos ver muchos de ellos en popular character encodings . Allí vemos el Windows-1252, el CP850, el ISO 8859-1 (Latin 1), el ISO 8859-15 (Latin 9) o el Unicode (con su sistema de codificación de longitud variable más típico, el UTF-8) , que son los que más nos interesan para el asunto que nos ocupa. En el artí*** de la WikiPedia Western Latin character sets tenemos una tabla mostrándonos las diferencias entre estos juegos de caracteres.

Antes de poner manos a la obra, es conveniente que verifiquemos que el bash nos muestra correctamente acentos, eñes y si acaso, el símbolo del euro € (aunque por estos lares el € no lo usamos...) escribiendo en un terminal á é í ó ú Á É Í Ó Ú ñ Ñ €. Si no salen bien, puede ser por dos motivos principalmente:
  1. El bash no está correctamente configurado para mostrar acentos. Esto ocurría bastante hace unos años, y era necesario hacer todo tipo de ajustes. Sin embargo, en las distribuciones actuales normalmente no es necesario hacer nada.
  2. La fuente usada en el terminal que estamos usando (Consola de Linux, Putty, Konsole, GNOME Terminal, etc.) no lleva acentos o no están correctamente mapeados.
Lo primero que tenemos que tener en mente es que el juego de caracteres que vamos a usar en Linux es el que especificamos en la variable LANG. Yo normalmente la tengo en inglés (ya he comentado alguna vez que es muy útil tener los errores y mensajes en inglés para poder buscarlos) y con el juego de caracteres de alfabetos latinos con el símbolo del Euro, el ISO 8859-15. Podemos ver en el siguiente ejemplo que si especificáramos un LANG no apropiado para nuestro entorno, como C, no veríamos ninguno de los caracteres especiales:
$ echo $LANG
en_US.ISO-8859-15
$ ls 0áéíóúñ€
0áéíóúñ€
$ export LANG=C
$ ls 0áéíóúñ€
0???????
Por tanto, la clave de este juego es siempre traducir de o desde el juego de caracteres ISO 8859-15.

Si necesitáramos reconfigurar qué juegos de caracteres queremos tener disponibles en Linux, podemos usar el comando:
dpkg-reconfigure locales
que nos hará las siguientes preguntas:




NTFS
:
El NTFS tiene las siguientes opciones de mount en relación a los juegos de caracteres:

iocharset=name Character set to use when returning file names. Unlike VFAT, NTFS suppresses names that contain unconvertible characters. Deprecated.
nls=name New name for the option earlier called iocharset.
utf8 Use UTF-8 for converting file names.
uni_xlate=[0|1|2] For 0 (or `no’ or `false’), do not use escape sequences for unknown Unicode characters. For 1 (or `yes’ or `true’) or 2, use vfat-style 4-byte escape sequences starting with “:”. Here 2 give a little-endian encoding and 1 a byteswapped bigendian encoding.

Para que el driver traduzca el juego de caracteres a nuestro ISO 8859-15 pondremos:
mount -t ntfs -o nls=iso8859-15 /dev/XXX /mnt/puntodemontaje

NTFS-3G
:
El NTFS-3G tiene la siguiente opción para que le especifiquemos qué juego de caracteres usar:

locale= You can set locale with this option which is often required to make visible files with national charaters. It’s useful if locale environment variables are not set before partitions had been mounted from /etc/fstab.

Por tanto el NTFS-3G usará lo que tengamos en el locale a menos que le especifiquemos lo contrario. En la siguiente secuencia de comandos podemos ver que si la variable LANG no soporta nuestros caracteres, los ficheros con dichos caracteres directamente ni aparecerán (en el root del filesystem hay un fichero llamado 0áéíóúñÑ€.txt). Si forzamos un locale en el comando ntfs-3g, el fichero ya aparecerá, aunque el bash no nos lo mostrará bien (pondrá símbolos de interrogación) por culpa precisamente de la variable LANG:
# export LANG=C
# ntfs-3g /dev/XXX /mnt/test
# ll /mnt/test/0*
ls: /mnt/test/0*: No such file or directory
# umount /mnt/test/
# ntfs-3g /dev/XXX /mnt/test/ -o locale=en_US.iso8859-15
# ll /mnt/test/0*
-rwxrwxrwx 1 root root 0 Apr 3 23:33 /mnt/test/0????????.txt*
# umount /mnt/test/
# export LANG=en_US.iso8859-15
# ntfs-3g /dev/XXX /mnt/test/
# ll /mnt/test/0*
-rwxrwxrwx 1 root root 0 2009-04-03 20:33 /mnt/test/0áéíóúñÑ€.txt*

VFAT:
El FAT tiene las siguientes opciones de mount en relación a los juegos de caracteres:

codepage=value Sets the codepage for converting to shortname characters on FAT and VFAT filesystems. By default, codepage 437 is used.
iocharset=value Character set to use for converting between 8 bit characters and 16 bit Unicode characters. The default is iso8859-1. Long filenames are stored on disk in Unicode format.
uni_xlate Translate unhandled Unicode characters to special escaped sequences. This lets you backup and restore filenames that are created with any Unicode characters. Without this option, a ‘?’ is used when no translation is possible. The escape character is ‘:’ because it is otherwise illegal on the vfat filesystem. The escape sequence that gets used, where u is the unicode character, is: ‘:’, (u & 0×3f), ((u>>6) & 0×3f), (u>>12).
utf8 UTF8 is the filesystem safe 8-bit encoding of Unicode that is used by the console. It can be be enabled for the filesystem with this option. If `uni_xlate’ gets set, UTF8 gets disabled.

La forma adecuada de usar el mount en este caso sería:
mount -t vfat -o iocharset=iso8859-15,codepage=850 /dev/XXX /mnt/puntodemontaje
Es importante darse cuenta de que codepage es lo que se usa para traducir los nombres cortos (8+3) de MS-DOS que se siguen guardando junto con los largos en un sistema de ficheros FAT, y que el iocharset es lo que usamos para traducir los nombres largos.

Aunque los nombres cortos apenas los usamos hoy en día, podemos ver en Windows cómo se han guardado con la opción /X del comando dir:
3/04/2007 19:04 13 HOF3C6~1 hoááéñÑÁ
Hay que tener en cuenta que el CP850 no contiene el símbolo del Euro (€), y que es el CP858 el que sí lo contiene, pero el CP858 no lo soportan ni MS-DOS ni Linux (bueno, según How to Display the Euro in MS-DOS and Windows DOS el MS-DOS realmente sí, si le ponemos ficheros del YEAR 2000 FIX PAK FOR IBM PC DOS 7)


SAMBA
:
El servidor Samba nos permite compatir nuestros directorios usando el mismo sistema que Windows. Si queremos que los clientes Windows vean bien los caracteres especiales de nuestros ficheros, tenemos que especificar las siguientes opciones en la sección [global] del fichero /etc/samba/smb.conf:
dos charset = 850
unix charset = ISO8859-15
Y a continuación ejecutar un:
/etc/init.d/samba reload

Opciones del Kernel:

Para finalizar, es importante comentar que el kernel de Linux también tiene que estar compilado con opciones adecuadas para nuestro entorno de forma que si no especificamos opciones siempre se escojan las adecuadas para nuestro entorno. Muestro las opciones interesantes en capturas de sesiones de make menuconfig.

En File Systems→Native Languaje Support es importante elegir todos los juegos de caracteres que vamos a necesitar y, sobre todo, especificar que nos interesa que el iocharset por defecto sea siempre iso8859-15:


En File Systems→DOS/FAT/NT Filsesystems especificamos el codepage y el iocharset por defecto para particiones FAT:

En File Systems→Network File Systems especificamos el codepage por defecto para montar shares SMB:


Bueno es todo... Creditos y agradecimientos a http://www.vicente-navarro.com/

No hay comentarios.: