Lo hice y lo entendí

El blog de Vicente Navarro
03 abr

Cómo mantener los acentos y las eñes al montar NTFS, FAT o 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 aquí en España. En el artículo 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 € 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:

dpkg-reconfigure locales 1

dpkg-reconfigure locales 2

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 20: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 2007-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 & 0x3f), ((u>>6) & 0x3f), (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).

SMBFS

El smbfs nos permite montar directorios compartidos remotamente por un Windows (o por un UNIX que use el protocolo SMB). Los parámetros que podemos usar en relación a los juegos de caracteres son los habituales:

iocharset=<arg>   sets the charset used by the Linux side for codepage to charset translations (NLS). Argument should be the name of a charset, like iso8859-1. (Note: only kernel 2.4.0 or later)
codepage=<arg> sets the codepage the server uses. See the iocharset option. Example value cp850. (Note: only kernel 2.4.0 or later)

Por tanto, una buena forma de montar un share samba que nos permita ver nuestros caracteres especiales sería:

mount -t smbfs -o iocharset=iso8859-15,codepage=cp850,username=usuario //servidor/share /mnt/puntodemontaje

Fijémonos en que aquí el codepage se especifica cp850 y no 850 como en el caso del VFAT. Esta diferencia la veremos también en las pantallas de configuración del kernel más abajo.

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 SystemsNative 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:

Kernel NLS 1

Kernel NLS 2

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

Kernel FAT

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

Kernel SMB

Entradas relacionadas

28 Comentarios a “Cómo mantener los acentos y las eñes al montar NTFS, FAT o smbfs y al compartir directorios con Samba”

  • rafa_piltrafa dice:

    Hola Vicente !!

    otro gran artículo. Realmente útil para los neófitos del linux.

    gracias !!
    rafa.

  • Ivan dice:

    Gracias por el artículo, muy bueno. Lo tendré en cuenta cuando monte el raid 1 y configure samba.

    Saludos, Iván.

  • rafa_piltrafa, Iván ¡Muchas gracias a los dos!

  • Sergio dice:

    Muy buen artículo, Vicente. Clarísimo.

    Tengo un problema relacionado. Tuve que montar un disco duro con NTFS en la máquina para copiar algunos archivos y, como no tenía tu artículo a mano, cometí el error de no mapear el charset. Ahora tengo la información en el disco duro y me salen los caracteres extraños. Lo peor es que no puedo quemar la información en un CD (se quejan los programas para quemarlos) y ya no tengo disponible el disco duro original. ¿Qué puedo hacer para convertir los caracteres?

    Saludos,

    Sergio

  • Sergio Gracias. Me suena el problema que comentas. A mí también me ha pasado alguna vez. Está difícil. Yo creo que intentaría identificar qué caracteres extraños salen por cada carácter con acento o ñ nuestro y haría un script que, usando sed recorriera todos los ficheros y sustituyera el carácter extraño de turno por el bueno. Algo como:

    for inicial in `ls`
    do
    final=`echo $inicial | sed 's/caracterraro/caracterdeseado/g'`
    mv $inicial $final
    done

    También podría valer usar “find” para recorrer más directorios en vez de “ls”.

  • sanatox dice:

    Hola!!!

    yo he escrito un script que hace esto ultimo que comentais. mirad:

    #!/bin/bash

    for i in `find $1`; do
    if [ `echo $i | grep "¢"` ]; then
    NOMBRE=`echo -e $i | tr -s ‘¢’ ‘ó’`
    mv $i $NOMBRE
    fi
    done

    Así sustituyo la dichosa ¢ por la ó. EL problema que tengo es que no se traga los nombres de directorios o ficheros con espacios, ya que al llegar un espacio en $i sólo se almacena hasta ahí. ¿alguna idea de cómo evitar ésto?

    Gracias

  • sanatox Prueba a poner el $NOMBRE entre comillas dobles (las dobles respetan las variables, las simples no) y así los espacios se mantendrán. Te pongo un ejemplo:

    # touch "fichero con espacios" 
    # NOMBRE="fichero con espacios"
    # mv $NOMBRE "nuevo nombre"
    mv: target `nuevo nombre' is not a directory
    # mv "$NOMBRE" "nuevo nombre"                                                          
    # ls "nuevo nombre"
    nuevo nombre
    

     
    Como puedes ver, si pongo $NOMBRE en vez de “$NOMBRE”, el:

    # mv $NOMBRE "nuevo nombre"
    

     
    es como si pusiera:

    # mv fichero con espacios "nuevo nombre"
    

     
    Es decir, que mueva los ficheros “fichero”, “con” y “espacios” al directorio “nuevo nombre”. Puedes ver que los nombres con espacios entre comillas simples son respetados. Por eso da el error: mv: target `nuevo nombre' is not a directory

  • Nahuel36 dice:

    excelente tutorial, muy completito, se agradece mucho! (Y)

    saludos

  • @Nahuel36 ¡Me alegro de que te haya resultado interesante!

  • leli dice:

    Hola,

    verás tengo un problema con samba. He seguido tu tutorial y ocurre lo siguiente: los contenidos de los archivos se ven bien, ya sea desde el servidor samba en debian o desde windows, todos los caracteres especiales se visualizan si problemas. Lo que ocurre es que los archivos que tienen caracteres en su nombre no se ven correctamente. He probado diferentes configuraciones pero no consigo que un usuario vea bien los caracteres desde Windows.

    A ver si me pueden echar una mano.

    Gracias por adelantado.

  • @leli Todo el documento está muy enfocado al uso del juego de caracteres ISO-8859-15, pero muchos sistemas están configurados con el locale UTF8, con lo cual tendrías que modificar las opciones a usar. Es posible que en tu caso vaya por ahí el problema.

  • leli dice:

    Gracias Super Coco. De todas maneras, ¿el problema sería ese aunque haya reconfigurado las locales para que use el ISO-8859-15?

    A parte de eso, en el tema del kernel no puedo hacer un ‘make menuconfig’. No sé si se debe a que es una máquina virtual, pero aún así he intentado bajarme paquetes con los headers pero nada.

    Un saludo.

  • @leli No, claro. Si el locale es el ISO-8859-15 ese no sería el problema y la configuración de Samba que aparece más arriba te debería de funcionar, igual que me funciona a mi.

    El "make menuconfig" es parte de la recompilación del kernel. Sobre el tema, igual te interesa: Compilar el kernel de Linux.

  • leli dice:

    Pues no sé, tengo la configuración clavada al tutorial pero no va, jeje. En fin miraré a fondo lo del kernel a ver si por ahí escapo.

    Gracias :)

  • a6m dice:

    Thx =)

    PD:

    mount -t ntfs -o utf /dev/XXX /mnt/puntodemontaje

    Si usas alguna utf ( por ejemplo ca_ES.UTF-8 o es_ES.UTF-8).

  • marpada dice:

    Excelente artículo, como todos los de este blog :D

    ¿que pasaría con los dispositivos extraibles que se montan automáticamente pero no se especifican en el fstab?

  • @marpada ¡Gracias! En ese caso, dependes de las opciones que los diferentes demonios de automontaje tengan configuradas por defecto. Si ejecutas “mount” tras el automontaje podrás ver las opciones usadas. Si no te sirven, desmonta y haz tú el montaje a mano o tendrás que investigar cómo cambiar las opciones del montaje automático.

  • ignacioanti dice:

    saludos quiero saber comopuedo montar un cd para ver las tildes, estoy usando debian lenny y los nombres de los archivos que llevan tilde me aparecen unos rectangulos en vez de la letra con tilde, pero en la consola si puedo escribir tildes y la ñ

  • josema dice:

    Hola a todos.

    A mí lo que me pasa en que en el teclado numérico del portátil, cuando utilizo el vim o el vi no funciona, me salen letras y saltos de línea.

    ¿Sabéis porqué?

    Gracias.

Trackbacks y pingbacks:

Tema LHYLE09, creado por Vicente Navarro