Por que meus nomes de arquivo parecem 'normais' no Linux, mas não remotamente no Windows?

11

Ao trabalhar com um colega, encontrei um problema estranho que parece relacionado à codificação. Estamos trabalhando com algumas imagens que têm nomes de arquivos suficientes simples, como city.gifou wine.gif, mas como se poderia esperar que as coisas ficam mais complicadas quando utilizar caracteres especiais, como é, ë, à. Também estamos trabalhando com dados holandeses que possuem esses caracteres, por exemplo café( pub ). (Não temos controle sobre a origem dos arquivos.) Aqui é onde os problemas começam a surgir. Os seguintes nomes de arquivo são apenas um exemplo. O problema também ocorre para outros caracteres com sinais diacríticos.

café-2.png
cafetaria.png
café.png

O primeiro e o último item devem ter um e acentuado (acentuação aigu, é). É assim que é mostrado no Linux (CentOS 6 e 7) em um terminal durante a execução ls. Mas aqui vem o Windows! (Usando o Windows 10, 64 bits.) Quando conectado no Windows por SSL com o servidor e depois ligando ls, a lista acima fica assim:

café-2.png
cafetaria.png
caf▒.png

Como você pode ver, a primeira linha ainda tem o e acentuado é, mas a terceira não. Em vez disso, vejo esse caractere - que está medium shadeem unicode (9618 decimal). Isso é estranho em si. No entanto, quando eu me conecto através do SFTP com o Filezilla (ainda no Windows), vejo o seguinte:

café-2.png
cafetaria.png
café.png

Então agora as coisas émudaram : no primeiro, mudou para a sequência e no terceiro está tudo bem. Eu descobri aqui que isso provavelmente ocorre devido a uma conversão de Latin-1 <-> UTF-8 que deu errado, se eu entendi direito. Mas isso não pode ser tudo o que está acontecendo, certo?

O Linux mostra tudo o que esperávamos, o Windows mostra um comportamento aparentemente inconsistente, dependendo da maneira como visualizamos o nome do arquivo (SSH (putty) ou SFTP (filezilla)). Existe uma maneira de "normalizar" esses nomes de arquivos - ou seja, editá-los - e garantir que eles sejam iguais em todos os sistemas operacionais; ou pelo menos consistente, e se sim, como? UTF-8é a nossa codificação de escolha.

Mesmo que isso possa ser apenas uma questão estética, não é. Ao tentar fazer o download de coisas através do SFTP no Windows em nosso servidor Linux, não consigo baixar os arquivos com o problema mencionado acima. O Filezilla lançará um erro como Can't download file café-2.png: café-2.png does not exist on the server. O que me parece que o Filezilla lê o diretório e o nome do arquivo, interpreta-o em alguma codificação, envia uma solicitação GET ao servidor com sua interpretação, mas essa interpretação difere do nome do arquivo Linux, portanto, o arquivo não é encontrado.

Por fim, seria bom se houvesse uma solução disponível, mesmo que eu também esteja interessado em saber por que isso acontece. Isso ocorre porque os arquivos de imagem foram possivelmente criados em diferentes sistemas operacionais? Isso ocorre porque o servidor Linux os interpreta errado ou o Windows está estragando? Espero que exista uma solução em que possamos simplesmente entrar em contato com o administrador do sistema e solicitar que ele ative um switch na configuração do servidor, mas acho que não é tão fácil assim.

Bram Vanroy
fonte
1
É uma questão do cliente (PuTTY, etc) e sua configuração, e não é relevante para o Windows. Para o PuTTY, isso é feito na seção de tradução .
9786 Thomas Dickey
2
Parece que o é em "café-2.png" é codificado em UTF-8, mas o é em "café.png" é codificado em ISO-8859-1. Você pode correr python -c "import sys; print(repr(sys.argv[1]))" café-2.pnge python -c "import sys; print(repr(sys.argv[1]))" café.png?
Oskar Skog
@OskarSkog Vou tentar isso de manhã. Mas eu sempre pensei que os nomes de arquivos não 'tivessem' uma codificação, em outras palavras: é como o sistema operacional deseja. Então, isso significa que os diferentes arquivos foram criados em diferentes sistemas operacionais? (Nós não temos nenhum controle sobre a origem dos arquivos.)
Bram Vanroy
No unix, como sistemas operacionais, o nome do arquivo é apenas uma sequência de bytes. O conceito de personagens chega em um nível superior.
Oskar Skog
1
Nem mesmo perto de uma resposta ou solução, apenas um pensamento na avenida a seguir. Pelo OP, parece que os arquivos podem ter origens variadas, sem controle sobre o nome gerado pela fonte, e é tarde demais para aplicar filtros para corrigir o snafus de nome de arquivo recebido. É provável que a solução envolva a execução de um script no servidor que possa detectar e corrigir erros de nome de arquivo, possivelmente até padronizando o conjunto de caracteres / página de código usada para nomes. Em seguida, o OP pode usar a mesma página de código no Filezilla ou em outro cliente, e tudo funcionará. Além das minhas habilidades, mas um caminho a seguir, talvez.
user207673

Respostas:

11

Mas aqui vem o Windows!

O Windows não tem nada a ver com isso. Você pode reproduzir este mesmo comportamento exato com uma instância local do (digamos) Terminal GNOME, com a codificação do terminal adequadamente seleccionados e localidade devidamente configurado para ls, sem qualquer Windows estar na foto em tudo .

A única coisa que o Windows faz é mostrar claramente o que está acontecendo aqui. O programa FTP do Windows está pegando os bytes nos nomes de arquivos e exibindo-os como os pontos de código relevantes na página de códigos 1252. Essa codificação de byte único com quase tudo acima de 0x1F um glifo imprimível nos informa exatamente quais são os bytes nos nomes de arquivos. .

Seu segundo nome de arquivo é pouco informativo, mas o primeiro e o terceiro são reveladores.

  • O primeiro nome do arquivo é a sequência de bytes 63 61 66 c3 a9 2d 32 2e 70 6e 67- na página de código 1252, esse é café-2.png. É também a codificação UTF-8 de café-2.png.
  • O terceiro nome do arquivo é a sequência de bytes 63 61 66 e9 2e 70 6e 67- na página de código 1252, esse é café.png. No entanto, não é uma codificação UTF-8 válida. e9inicia uma sequência de codificação de caracteres incompleta.

Então, o que está acontecendo é que as coisas não estão usando a página de código 1252, mas estão usando UTF-8, ou seja, sua sessão SSH e seu emulador de terminal local, estão manipulando o UTF-8 válido da mesma maneira que um outro, mas estão manipulando o UTF-8 inválido de duas maneiras diferentes:

  • Provavelmente o que está exibindo o gráfico de blocos está simplesmente usando esse gráfico de bloco como o caractere geral de saída de substituição para sequências UTF-8 inválidas.
  • O que está exibindo a letra éestá voltando para a Página de Código 1252 quando encontra uma codificação inválida.

Seu problema subjacente é um sistema que de alguma forma está gerando alguns nomes de arquivos codificados como UTF-8 e outros nomes de arquivos codificados na Página de Código 1252.

JdeBP
fonte
Não concordo que o Windows não tenha nada a ver com isso. Provavelmente não aconteceria em outro Linux. O problema é a codificação padrão e um novo Windows (ou pelo menos já usou) seu CP e não UTF, resultando nesse problema mesmo no mesmo sistema operacional em todos os países. Você pode reproduzir este em Linux, mas Linux é mais consistente na escolha Unicode
MatthewRock
Olá! Obrigado pela resposta elaborada. Você se concentra no que está acontecendo, o que é legal: eu sempre gosto de entender o que está acontecendo. Mas você poderia esclarecer por que isso está acontecendo e como podemos combater os problemas decorrentes dessa inconsistência? Eu adicionei dois parágrafos para esclarecer o que quero dizer.
Bram Vanroy 7/03
Eu me pergunto por que os dois "cafés" são mostrados da mesma forma quando não são. O ls (1) do GNU tem um tratamento de erro de codificação ridículo?
Oskar Skog
@MatthewRock Nesse caso, acho que o Windows realmente não tem nada a ver com isso. Não estou feliz com a maior parte do que o M $ faz, e de bom grado admito muitos de seus males, mas não vejo culpa dada onde não é devido. Como a resposta deixa claro, o problema está nos valores de bytes dos próprios nomes. Nesse caso, o Windows expôs o sintoma, mas não é o problema. Não é mais que o termômetro o problema quando mostra que a febre é de 104 °. O problema se origina em qualquer processo que tenha criado os nomes no servidor que possui os arquivos que o OP está tentando acessar.
user207673
Você poderia fornecer mais informações e possíveis soluções? Caso contrário, gastei minha recompensa por nada.
Bram Vanroy 15/03