En un sistema de archivos donde los nombres de archivo están en UTF-8, tengo un archivo con un nombre defectuoso; se muestra como:, D�sinstallernombre real de acuerdo con zsh:, D$'\351'sinstallerLatin1 para Désinstallersí mismo, una barbarie francesa para "desinstalar". Zsh no coincidiría con él, [[ $file =~ '^.*$' ]]pero lo haría con un problema: este *es el comportamiento que espero.
Ahora todavía espero encontrarlo cuando lo find . -name '*'ejecuto; de hecho, nunca esperaría que un nombre de archivo falle esta prueba. Sin embargo, con LANG=en_US.utf8, el archivo no aparece, y tengo que configurarlo LANG=C(o en_US, o '') para que funcione.
Pregunta: ¿Cuál es la implementación detrás y cómo podría haber predicho ese resultado?
Información: Arch Linux 3.14.37-1-lts, find (GNU findutils) 4.4.2

convmvconvertir nombres de archivo a utf-8?[[ $file =~ '^.*$' ]]no usarrecodeel nombre del archivo, pero ahora lo investigaréconvmvsi es necesario. Gracias.Respuestas:
Esa es una muy buena captura. De un vistazo rápido al código fuente de GNU find, diría que esto se reduce a cómo se
fnmatchcomporta en secuencias de bytes no válidas (pred_name_commonenpred.c):Este código prueba el valor de retorno de
fnmatchigualdad con 0, pero no verifica los errores; esto da como resultado que cualquier error sea reportado como "no coincide".Se sugirió, hace muchos años, cambiar el comportamiento de esta función libc para que siempre devuelva verdadero en el
*patrón, incluso en nombres de archivos rotos, pero por lo que puedo decir, la idea debe haber sido rechazada (vea el hilo que comienza en https : //sourceware.org/ml/libc-hacker/2002-11/msg00071.html ):Según lo mencionado por Stéphane Chazelas en un comentario, y también en el mismo hilo de 2002, esto es inconsistente con la expansión glob realizada por los proyectiles, que no ahogan los caracteres no válidos. Quizás aún más desconcertante es el hecho de que revertir la prueba solo coincidirá con aquellos archivos que tienen nombres rotos (cree archivos en bash con
touch $'D\351marrer' $'Touch\303\251' $'\346\227\245\346\234\254\350\252\236'):Entonces, para responder a su pregunta, podría haber predicho esto al conocer el comportamiento de su
fnmatchen este caso y al saber cómofindmaneja el valor de retorno de esta función; probablemente no podría haberlo descubierto únicamente leyendo la documentación.fuente
*es que entonces sería incompatible conD*staller.D*stallercoincidiera$'D\351sinstaller'tan bien como en el conjunto de todos los proyectiles que he probado. Dado que el comportamiento de GNU fnmatch no es consistente con el del shell GNU, diría que es un error..solo debe coincidir con caracteres válidos en la codificación, de ahí mi expectativa de que.*no coincida con cadenas no válidas, pero no puedo encontrar una especificación coincidente para la estrella globbing.-name '*'coincide con todos los archivos, incluidos los nombres rotos incluidos), por lo que presumiblemente es la versión de BSDfnmatch, que no reclama POSIX.2 cnoformance, a diferencia de la versión de GNU, tiene una interpretación diferente y posiblemente más sensata de lo que se debe hacer con caracteres no válidos.La
-nameopción de búsqueda utiliza la notación de coincidencia de patrón de shell para realizar la coincidencia del nombre de archivo.*es un patrón que coincide con varios caracteres , debe coincidir con una cadena de cero o más caracteres.findusa fnmatch para verificar la coincidencia de patrones, por lo que puede usar ltrace para verificar el resultado:Con
D\351sinstaller,fnmatchreturn-1, indicó que no pudo coincidir. Seሒaaemparejará un carácter válido como .En su caso, con la
UTF-8configuración regional,\351es un carácter no válido, lo que hace que falle la coincidencia de patrones.fuente
ltrace. Lo sabíastrace, peroltracees nuevo para mí. ¡Encantador!