Dlaczego moje nazwy plików wyglądają „normalnie” w systemie Linux, ale nie zdalnie w systemie Windows?

11

Podczas pracy z kolegą znalazłem dziwny problem, który wydaje się związany z kodowaniem. Pracujemy z niektórych obrazów, które mają dość proste nazwy plików, takich jak city.gifczy wine.gif, ale jak można się spodziewać rzeczy uzyskać bardziej skomplikowane przy użyciu znaków specjalnych, takich jak é, ë, à. Pracujemy również z danymi holenderskimi, które mają te znaki, np. café( Pub ). (Nie mamy kontroli nad pochodzeniem plików.) Tutaj zaczynają się pojawiać problemy. Następujące nazwy plików są tylko przykładem. Problem występuje również w przypadku innych znaków z znakami diakrytycznymi.

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

Pierwszy i ostatni element powinien mieć akcentowane e (accent aigu, é). Tak to pokazano w Linuksie (CentOS 6 i 7) w terminalu podczas działania ls. Ale nadchodzi Windows! (W systemie Windows 10, wersja 64-bitowa). Po połączeniu w systemie Windows za pomocą protokołu SSL z naszym serwerem, a następnie wywołaniu ls, powyższa lista wygląda następująco:

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

Jak widać, pierwsza linia nadal ma akcentowane e é , ale trzecia nie. Zamiast tego widzę ten znak - który jest medium shadew standardzie Unicode (dziesiętnie 9618). To samo w sobie dziwne. Kiedy jednak łączę się przez SFTP z Filezillą (wciąż w systemie Windows), widzę to:

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

Więc teraz wszystko się zmieniło: w pierwszym ézmieniło się w sekwencję, w trzecim wszystko jest w porządku. Odkryłem tutaj, że najprawdopodobniej jest to spowodowane konwersją Latin-1 <-> UTF-8, która poszła nie tak, jeśli dobrze to zrobię. Ale to nie wszystko, co się dzieje, prawda?

Linux pokazuje wszystko tak, jak się spodziewaliśmy, Windows wydaje się pozornie niespójnym zachowaniem w zależności od sposobu, w jaki patrzymy na nazwę pliku (SSH (kit) lub SFTP (filezilla)). Czy istnieje sposób na „znormalizowanie” tych nazw plików - tj. Ich edycję - i upewnienie się, że wszystkie są takie same w każdym systemie operacyjnym; a przynajmniej spójne, a jeśli tak, to w jaki sposób? UTF-8jest naszym kodowaniem z wyboru.

Chociaż może to być tylko kwestia estetyczna, tak nie jest. Podczas próby pobrania rzeczy za pośrednictwem SFTP w systemie Windows z naszego serwera Linux nie mogę pobrać plików, których dotyczy problem wspomniany powyżej. Filezilla zgłosi błąd, taki jak Can't download file café-2.png: café-2.png does not exist on the server. Co wydaje mi się, że Filezilla odczytuje katalog i nazwę pliku, interpretuje je w pewnym kodowaniu, wysyła żądanie GET do serwera z jego interpretacją, ale ta interpretacja różni się od nazwy pliku Linux, więc plik nie został znaleziony.

Ostatecznie byłoby miło, gdyby było dostępne rozwiązanie, chociaż jestem również zainteresowany tym, dlaczego tak się dzieje. Czy to się dzieje, ponieważ pliki obrazów zostały prawdopodobnie utworzone w różnych systemach operacyjnych? Czy to się dzieje, ponieważ serwer Linux źle je interpretuje, czy system Windows się psuje? Mamy nadzieję, że istnieje rozwiązanie, w którym możemy po prostu skontaktować się z naszym sysadminem i poprosić go o włączenie przełącznika w konfiguracji serwera, ale obawiam się, że nie jest to takie proste.

Bram Vanroy
źródło
1
Jest to kwestia klienta (PuTTY itp.) I ich konfiguracji, a nie dotyczy systemu Windows. W przypadku PuTTY odbywa się to w sekcji tłumaczeń .
Thomas Dickey,
2
Wygląda to tak, jakby é w „café-2.png” było zakodowane w UTF-8, ale é w „café.png” jest zakodowane zgodnie z ISO-8859-1. Umiesz biegać python -c "import sys; print(repr(sys.argv[1]))" café-2.pngi python -c "import sys; print(repr(sys.argv[1]))" café.png?
Oskar Skog
@OskarSkog Spróbuję tego rano. Ale zawsze myślałem, że nazwy plików „nie mają” kodowania, innymi słowy: jest tak, jak chce tego system operacyjny. Czy to oznacza, że ​​różne pliki zostały utworzone w różnych systemach operacyjnych? (Nie mamy kontroli nad pochodzeniem plików.)
Bram Vanroy,
W systemach operacyjnych typu Unix nazwa pliku to tylko ciąg bajtów. Pojęcie postaci wchodzi na wyższy poziom.
Oskar Skog
1
Nie jest nawet blisko odpowiedzi lub rozwiązania, a jedynie refleksja nad drogą, którą należy podążać. Z PO wydaje się, że pliki mogły mieć różne pochodzenie, bez żadnej kontroli nad nazwą generowaną przez źródło, i jest już za późno, aby zastosować filtry, aby poprawić przychodzącą nazwę pliku snafus. Rozwiązanie najprawdopodobniej będzie wymagało uruchomienia skryptu na serwerze, który może wykrywać i poprawiać błędy w nazwach plików, a nawet standaryzować zestaw znaków / stronę kodową używaną dla nazw. Wtedy OP może użyć tej samej strony kodowej w Filezilli lub innym kliencie i wszystko będzie działać. Poza moimi umiejętnościami, ale być może tropem do naśladowania.
user207673,

Odpowiedzi:

11

Ale nadchodzi Windows!

Windows nie ma z tym nic wspólnego. Można odtworzyć ten sam dokładnie zachowanie z lokalnej instancji (powiedzmy) gnome-terminal, z odpowiednio dobranym kodowania terminala i odpowiednio skonfigurowanym dla lokalizacji ls, bez systemu Windows jest na zdjęciu w ogóle .

Jedyną rzeczą, którą robi Windows, jest jasne pokazanie, co się tutaj dzieje. Twój program FTP dla systemu Windows pobiera bajty z nazw plików i wyświetla je jako odpowiednie punkty kodowe na stronie kodowej 1252. To jednobajtowe kodowanie z prawie wszystkim powyżej 0x1F glifu do wydrukowania mówi nam dokładnie, jakie bajty w nazwach plików są .

Druga nazwa pliku jest w dużej mierze pozbawiona informacji, ale pierwsza i trzecia mówią.

  • Pierwsza nazwa pliku to sekwencja bajtów 63 61 66 c3 a9 2d 32 2e 70 6e 67- na stronie kodowej 1252 jest to café-2.png. Jest to również kodowanie UTF-8 café-2.png.
  • Trzecia nazwa pliku to sekwencja bajtów 63 61 66 e9 2e 70 6e 67- na stronie kodowej 1252 jest to café.png. Nie jest to jednak prawidłowe kodowanie UTF-8. e9rozpoczyna niekompletną sekwencję kodowania znaków.

Tak więc dzieje się tak, że rzeczy nie używają strony kodowej 1252, ale używają UTF-8, a mianowicie sesji SSH i lokalnego emulatora terminala, obsługują poprawny UTF-8 w taki sam sposób, ale obsługują nieprawidłowy UTF-8 na dwa różne sposoby:

  • Ten, który wyświetla grafikę blokową, najprawdopodobniej po prostu używa tej grafiki blokowej jako ogólnego zastępczego znaku wyjściowego dla nieprawidłowych sekwencji UTF-8.
  • Ten, który wyświetla literę, éwraca do kodu Page 1252, gdy napotka nieprawidłowe kodowanie.

Twoim podstawowym problemem jest system, który w jakiś sposób generuje niektóre nazwy plików zakodowane jako UTF-8 i inne nazwy plików zakodowane w Kodzie Strona 1252.

JdeBP
źródło
Nie zgadzam się, że Windows nie ma z tym nic wspólnego. Prawdopodobnie nie miałoby to miejsca na innym Linuksie. Problemem jest domyślne kodowanie, a afaik Windows użył (a przynajmniej użył) swojego CP, a nie UTF, co powoduje, że problem występuje nawet w tym samym systemie operacyjnym w różnych krajach. Możesz to odtworzyć w systemie Linux, ale Linux jest bardziej konsekwentny w wyborze Unicode
MatthewRock
Cześć! Dziękuję za wyszukaną odpowiedź. Skupiasz się na tym, co się dzieje, co jest miłe: zawsze lubię rozumieć, co się dzieje. Ale czy mógłbyś rzucić nieco światła na to, dlaczego tak się dzieje i jak możemy przeciwdziałać problemom wynikającym z tej niespójności? Dodałem dwa akapity, aby wyjaśnić, co mam na myśli.
Bram Vanroy,
Zastanawiam się, dlaczego obie „kawiarnie” są pokazywane tak samo, gdy nie są. Czy ls (1) GNU ma absurdalną obsługę błędów kodowania?
Oskar Skog
@MatthewRock W tym przypadku myślę, że Windows naprawdę nie ma z tym nic wspólnego. Nie jestem zadowolony z większości tego, co robi M $, i chętnie przyznam się do wielu złych rzeczy, ale nie widzę winy, gdy nie należy się żadna. Jak wyjaśnia odpowiedź, problemem są wartości bajtowe samych nazw. W tym przypadku system Windows ujawnił objaw, ale nie stanowi problemu. Problemem jest tylko termometr, który pokazuje, że gorączka wynosi 104 °. Problem pochodzi z procesów, które utworzyły nazwy na serwerze, który ma pliki, do których OP próbuje uzyskać dostęp.
user207673,
Czy możesz podać więcej informacji i możliwe rozwiązania? W przeciwnym razie nagrodę wydałem na nic.
Bram Vanroy,