Jak wprowadzić znaki specjalne, aby Bash / Terminal je zrozumiał?

18

Powiedzmy, że folder ma plik o nazwie Näyttökuva.png(dla zainteresowanych jest to „zrzut ekranu” po fińsku). Oto co się dzieje:

$ ls
Näyttökuva.png

$ ls N*
Näyttökuva.png

$ ls Nä*
ls: Nä*: No such file or directory

Wpływa to również na automatyczne uzupełnianie tabulatorów. Jeśli zacznę pisać ls Ni nacisnę tab, zostanie poprawnie rozwinięty do ls Näyttökuva.png. Ale jeśli zacznę pisać, ls Nätabulacja nic nie robi.

Jak mogę:

  • Skonfiguruj bash / terminal, aby rozumiał znaki specjalne
  • wpisz znaki specjalne, aby bash / terminal je rozumiał?

W Terminalu kodowanie jest ustawione na UTF-8 w zakładce Ustawienia, a zakładka Kodowanie jest w stanie domyślnym, tj. UTF-8, Mac OS Roman, ISO Latin 1, ISO Latin 9, Windows Latin 1, ASCII, NextStep + niektóre kodowania azjatyckie są włączone.


Nawet nieznajomy (choć prawdopodobnie nie jest niezbędny do pytania):

Jeśli piszę ls N, naciskaj tab, usuwaj znaki od końca, aż będzie czytać, ls Näi naciśnij tabponownie, polecenie rozwija się do ls Nättökuva.png[sic].

Jeśli spróbuję skasować litery po raz drugi ls Näi naciśniesz tab, rozwinie się do ls Nätökuva.png. Trzeci przebieg rozszerza się do ls Näökuva.png.

Z jakiegoś powodu czwarty bieg daje ls Nä̈kuva.png(zauważ, że umlauts nad umlautami). Tabting ls Nä̈daje za ls Nä̈kuva.pngkażdym razem. Niemniej jednak działa:

$ ls Nä̈kuva.png
Näyttökuva.png

$ history 2
518  ls Näyttökuva.png 
519  history 2
Jari Keinänen
źródło

Odpowiedzi:

23

Myślę, że bash potyka się o pewne anomalie w sposobie traktowania znaków akcentowanych. Możesz wziąć trochę popcornu, ponieważ będzie to trochę techniczne ...

Unicode pozwala na reprezentację niektórych znaków akcentowanych na kilka różnych sposobów: jako „punkt kodowy” reprezentujący znak akcentowany lub jako szereg punktów kodowych reprezentujących nieakcentowaną wersję znaku, a następnie akcent (y). Na przykład „ä” może być reprezentowane albo jako U + 00E4 (UTF-8 0xc3a4, łacińska mała litera 1 z diaeresy) lub rozkładane jako U + 0061 U + 0308 (UTF-8 0x61cc88, mała łacińska a + łącząca diaeresis ).

System plików HFS + w OS X wymaga, aby wszystkie nazwy plików były przechowywane w reprezentacji UTF-8 w ich całkowicie rozłożonej formie . W nazwie pliku HFS + „ä” MUSI być zakodowany jako 0x61cc88, a „ö” MUSI być zakodowany jako 0x6fcc88.

Jestem prawie pewien, że dzieje się tutaj to, że kiedy wpiszesz „Näyttökuva.png” w wierszu poleceń, „wpisuje” znaki w złożonej formie. Po utworzeniu pliku system plików rozkłada znaki do przechowywania. Jak dotąd wszystko jest w porządku. Ale kiedy próbujesz użyć uzupełniania tabulatora zaczynającego się od „Nä”, myślę, że bash nie dekomponuje „ä” przed wyszukiwaniem dopasowań i oczywiście go nie znajduje.

Aby zilustrować różnicę, oto przykład tego, jakie kodowanie jest używane, gdy po prostu wpisuję „Näyttökuva.png” w wierszu poleceń, w porównaniu do tego, co jest używane, gdy przechowuję go jako nazwę pliku i używam uzupełniania tabulatorem, aby go wypełnić:

$ printf Näyttökuva.png | xxd    # This time I pasted the it in from this web page
0000000: 4ec3 a479 7474 c3b6 6b75 7661 2e70 6e67  N..ytt..kuva.png
$ touch Näyttökuva.png           # Also pasted from the web
$ printf Näyttökuva.png | xxd    # This time I tab-completed it after N
0000000: 4e61 cc88 7974 746f cc88 6b75 7661 2e70  Na..ytto..kuva.p
0000010: 6e67                                     ng

Jeśli chodzi o zagubienie się postaci podczas usuwania i ponownego wprowadzania kart, podejrzewam, że jest to ściśle powiązane. W szczególności myślę, że bash „usuwa” jeden punkt kodowy za naciśnięciem klawisza Delete, ale usuwa jeden znak z okna Terminala za naciśnięciem. Ponieważ jeden z usuniętych znaków (tym razem „ö”) składał się z dwóch punktów kodowych, ale tylko jednego znaku, wyświetlacz terminala nie synchronizuje się. Spróbuj uzupełnić tabulatorem całą nazwę pliku, usunąć ją z powrotem do „Näytt”, a następnie ponownie uzupełnij tabulatorem: bash wydaje się myśleć, że usunięto tylko łączącą diaeresis, a nie całe „ö”, więc ponownie dodaje łączącą diaeresis , ale tym razem dołącza się do „t”:

$ echo Näytkuva.png 
Näyttökuva.png

Zauważ, że kiedy naciskam return, bash faktycznie ma tam całą nazwę pliku; to tylko wyświetlacz terminala był zdezorientowany.

Bash TL; DR zawiera kilka błędów związanych z rozkładanymi znakami akcentowanymi.

EDYCJA: po pewnym zastanowieniu, myślę, że jedynym pełnym rozwiązaniem jest naprawienie bash (/ poczekaj, aż deweloperzy go naprawią). Może też istnieć sposób wprowadzania znaków w rozłożonej formie, ale nie mam pojęcia, co by to było. Ale znalazłem częściowe obejścia:

  1. Przeciąganie i upuszczanie pliku z Findera wkleja w prawidłowej formie. Ponieważ Finder pobiera nazwę pliku z systemu plików, jest on już rozłożony, więc po prostu działa.

  2. Możesz właściwie uzupełnić tabulatorem samą akcentowaną postać. Na przykład, jeśli wpiszesz „Na”, a następnie tabulator, będzie pasować do „Näyttökuva.png”, ponieważ rozkład kanoniczny „ä” zaczyna się od „a”. Ale jeśli masz plik o nazwie „Narwal.gif” w tym samym katalogu, nie będzie to bardzo pomocne ...

  3. Nie testowałem tego, ale jeśli powiążesz tabulację z menu-kompletnym zamiast kompletnego, powinno to umożliwić tabulowanie możliwych dopasowań, abyś mógł wybrać ten, który chcesz, nawet jeśli nie możesz wpisać następnej litery. (Lub możesz powiązać go z innym naciśnięciem klawisza, więc możesz go używać tylko wtedy, gdy jest to konieczne).

  4. Aby rozwiązać problem z brakiem synchronizacji wyświetlacza terminala, możesz powiązać coś z przerysowaniem linii prądu - nie zapobiegnie to wystąpieniu problemu, ale da ci możliwość ponownej synchronizacji wyświetlacza.

Gordon Davisson
źródło
Dzięki, podobał mi się popcorn. Myślę, że udało ci się ustalić przyczynę problemu: używanie $ echo -e "N\xC3\xA4*" | ls(echo daje Nä*) wyników Näyttökuva.png. Problem istnieje również w przypadku innych powłok w systemie Mac OS; i np. zsh ls Nzostaje automatycznie uzupełnione dols Na<0308>ytto<0308>kuva.png
Jari Keinänen
Próbowałem również autouzupełniania i ls Nä*bash w Xubuntu i działało to poprawnie, więc zawiera błędy między klawiaturą a OS X i terminalem. Przetestowałem to również na partycji Bootcamp, ale problem nadal występuje (tzn. Nie dzieje się tak tylko w przypadku plików HFS +).
Jari Keinänen,
(Teraz zobaczyłem Twoją edycję dotyczącą obejść). Przynajmniej dwie pierwsze prace. # 2 jest interesujące: autouzupełnianie Nadziała, ale Naynie działa (chociaż jest zrozumiałe, ponieważ tak naprawdę jest ¨pomiędzy ai y. W Xubuntu ls Na*nie działa (choć Nä*działa, więc to naprawdę nie jest problem). Jeśli chodzi o symbole wieloznaczne - może być jeszcze jedno obejście zastąpienie äi öz a?i o?np ls Na?y*Oczywiście zwiększa to dwuznaczności, ale to może się przydać w niektórych przypadkach..
Jari Keinanen
2
Powodem, dla którego działa w Xubuntu, może być po prostu to, że system plików ma tę samą formę co interfejs terminala. Jeśli robisz to ls N* | xxdw Xubuntu, czy daje on znaki złożone lub rozłożone?
Gordon Davisson
Zakładając, że Xubuntu przechowuje nazwę pliku w skomponowanej formie, spróbuj uruchomić polecenie touch $'Na\xcc\x88ytto\xcc\x88kuva.png'i zobacz, co się stanie - domyślam się, że utworzy nowy plik o bardzo bardzo podobnej nazwie.
Gordon Davisson
4

To stare pytanie, na które nie ma jednoznacznej odpowiedzi. Tylko obejścia.

Jednak połączyłem niektóre informacje z tego starego przewodnika i zgodnie z sugestiami i instrukcjami tutaj :

Zainstalowałem nowszą wersję bash w Snow Leopard. Po jego zainstalowaniu zakończenie bash działa poprawnie! (Snow Leopard jest dostarczany z wersją 3.2.48 (1) i zainstalowanym MacPorts 4.2.45_1). Pamiętaj, aby wprowadzić zmiany /etc/shellsi uruchomić chsh.

Ponadto, z powodu niektórych innych instrukcji, mam w .inputrc:

set meta-flag on
set input-meta on
set output-meta on
set convert-meta off

Nie jestem pewien, czy są one wymagane, czy nie do prawidłowego działania.

Dziki pingwin
źródło
Masz rację: bash 4.2 kończy się (gdzie äjest wstępnie skomponowany), Näyttökuva.pngale bash 3.2 nie.
Lri