Как ввести специальные символы, чтобы Bash / Terminal понимал их?

18

Допустим, в папке есть файл с именем Näyttökuva.png(для тех, кто заинтересован, это «скриншот» на финском языке). Вот что происходит:

$ ls
Näyttökuva.png

$ ls N*
Näyttökuva.png

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

Это также влияет на автоматическое завершение табуляции. Если я начну печатать ls Nи нажать, tabон будет правильно расширен до ls Näyttökuva.png. Но если я начну печатать, ls Näтабуляция ничего не даст.

Как я могу либо:

  • настроить bash / терминал так, чтобы он понимал специальные символы
  • введите специальные символы, чтобы bash / Terminal понимал их?

В Терминале кодировка UTF-8 установлена ​​на вкладке «Настройки», а вкладка «Кодировка» находится в состоянии по умолчанию, т.е. UTF-8, Mac OS Roman, ISO Latin 1, ISO Latin 9, Windows Latin 1, ASCII, NextStep + некоторые азиатские кодировки включены.


Даже незнакомец (хотя, вероятно, не существенный для вопроса):

Если я набираю ls N, нажимаю tab, удаляю символы с конца до тех пор, пока он не прочитает, ls Näи tabснова нажимаю, команда расширяется до ls Nättökuva.png[sic].

Если я попытаюсь удалить буквы во второй раз назад ls Näи нажать клавишу табуляции, она расширится до ls Nätökuva.png. Третий пробег расширяется до ls Näökuva.png.

По какой-то причине 4-й прогон дает ls Nä̈kuva.png(обратите внимание на умлауты над умлаутами). Вкладка ls Nä̈дает ls Nä̈kuva.pngкаждый раз. Тем не менее, это работает:

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

$ history 2
518  ls Näyttökuva.png 
519  history 2
Яри ​​Кейнянен
источник

Ответы:

23

Я думаю, что bash запутывается из-за некоторых аномалий в том, как обрабатываются акцентированные символы. Вы могли бы хотеть захватить немного попкорна, потому что это собирается стать техническим для немного ...

Юникод позволяет отображать некоторые акцентированные символы несколькими различными способами: в виде «кодовой точки», представляющей акцентированный символ, или в виде последовательности кодовых точек, представляющих безударную версию символа, за которой следует акцент (ы). Например, «ä» может быть представлен либо предварительно составленным как U + 00E4 (UTF-8 0xc3a4, латинская строчная буква 1 с диарезом), либо разложенным как U + 0061 U + 0308 (UTF-8 0x61cc88, латинская строчная буква a +, сочетающим диарез ).

Файловая система OS X HFS + требует, чтобы все имена файлов были сохранены в представлении UTF-8 их полностью разложенной формы . В имени файла HFS + «ä» ДОЛЖЕН быть закодирован как 0x61cc88, а «ö» ДОЛЖЕН быть закодирован как 0x6fcc88.

Я почти уверен, что здесь происходит то, что когда вы набираете «Näyttökuva.png» в командной строке, он «печатает» символы в заранее составленном виде. Когда файл создан, файловая система разлагает символы для хранения. Пока все хорошо. Но когда вы пытаетесь использовать завершение табуляции, начинающееся с «Nä», я думаю, что bash не может разложить «ä» перед поиском совпадений, и, конечно, он не находит их.

Чтобы проиллюстрировать разницу, вот пример того, какая кодировка используется, когда я просто набираю «Näyttökuva.png» в командной строке, по сравнению с тем, что используется, когда я сохраняю его как имя файла и использую завершение табуляции для его заполнения:

$ 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

Теперь, что касается потери символов при удалении и повторном завершении табуляции, я подозреваю, что это тесно связано. В частности, я думаю, что bash «удаляет» одну кодовую точку за нажатие клавиши удаления, но стирает один символ из окна терминала за нажатие. Поскольку один из удаленных символов (на этот раз «ö») состоял из двух кодовых точек, но только из одного символа, дисплей терминала не синхронизирован. Попробуйте завершить табуляцию всего имени файла, удалив его обратно в «Näytt», а затем повторно завершить табуляцией: bash, похоже, думает, что был удален только комбинированный диарез, а не весь «ö», поэтому он повторно добавляет комбинирующий диарез , но на этот раз он прикрепляется к «т»:

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

Обратите внимание, что когда я нажимаю return, bash на самом деле содержит все имя файла; это просто дисплей терминала, который был сбит с толку.

TL; DR bash имеет некоторые ошибки обработки разборных акцентированных символов.

РЕДАКТИРОВАТЬ: после некоторого размышления, я думаю, что единственное полное решение - это исправить bash (/ ждать, пока его разработчики исправят это). Также может быть способ ввода символов в разложенном виде, но я понятия не имею, что это будет. Но я нашел некоторые частичные обходные пути:

  1. Перетащите файл из Finder и вставьте его в правильном виде. Поскольку Finder получает имя файла из файловой системы, он уже разложен, поэтому он просто работает.

  2. Вы можете фактически завершить табуляцию самого акцентированного символа. Например, если вы введете «Na», а затем нажмите «tab», он будет соответствовать «Näyttökuva.png», потому что каноническое разложение «ä» начинается с «a». Но если у вас есть файл с именем "Narwal.gif" в том же каталоге, это не очень поможет ...

  3. Я не проверял это, но если вы привязываете вкладку к завершенному меню, а не к полному, она должна позволить вам переключаться между возможными совпадениями, чтобы вы могли выбрать желаемое, даже если вы не можете набрать следующую букву. (Или вы можете связать его с другим нажатием клавиши, поэтому вы можете использовать его только тогда, когда вам нужно.)

  4. Для устранения проблемы с синхронизацией дисплея терминала вы можете привязать что-либо к redraw-current-line - это не предотвратит возникновение проблемы, но даст вам возможность повторно синхронизировать дисплей.

Гордон Дэвиссон
источник
Спасибо, мне понравился попкорн. Я думаю, что вы пригвоздили причину проблемы: использование $ echo -e "N\xC3\xA4*" | ls(эхо дает Nä*) результаты Näyttökuva.png. Проблема существует и с другими оболочками в Mac OS; и, например, zsh ls Nавтоматически заполняется доls Na<0308>ytto<0308>kuva.png
Jari Keinänen
Я также попробовал автозаполнение и ls Nä*в bash в Xubuntu, и оно работало должным образом, поэтому оно дает ошибку где-то между клавиатурой, OS X и терминалом. Я также проверил это в разделе Bootcamp, но проблема сохраняется (то есть, это происходит не только с файлами HFS +).
Яри ​​Кейнянен
(Теперь увидел ваши правки относительно обходных путей) По крайней мере первые две работы. # 2 интересен: автозаполнение Naработает, но Nayне работает (хотя это понятно, потому что на самом деле есть ¨между aи y. В Xubuntu ls Na*не работает (хотя Nä*работает, так что на самом деле это не проблема). Что касается подстановочных знаков - еще один обходной путь может быть замена äи öс a?и , o?например , ls Na?y*это , конечно , увеличивает неопределенность, но может быть полезен в некоторых случаях..
Яри Кейнянен
2
Причина, по которой он работает в Xubuntu, может заключаться в том, что файловая система использует ту же форму, что и интерфейс терминала. Если вы делаете ls N* | xxdв Xubuntu, дает ли он составные или разложенные символы?
Гордон Дэвиссон
Предполагая, что Xubuntu хранит имя файла в сложенном виде, попробуйте запустить команду touch $'Na\xcc\x88ytto\xcc\x88kuva.png'и посмотреть, что произойдет, - я предполагаю, что он создаст новый файл с очень очень похожим именем.
Гордон Дэвиссон
4

Это старый вопрос, и нет однозначного ответа. Просто обходные пути.

Однако я объединил некоторую информацию из этого старого руководства, и как предложено и проинструктировано здесь :

Я установил новую версию Bash в своем Snow Leopard. После его установки, завершение bash работает правильно! (Snow Leopard поставляется с 3.2.48 (1) и MacPorts с 4.2.45_1). Не забудьте вносить изменения /etc/shellsи работать chsh.

Кроме того, из-за некоторых других инструкций, я имею в .inputrc:

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

Не уверен, если они необходимы или не для правильной работы.

Дикий пингвин
источник
Вы правы: bash 4.2 завершает (где äпредварительно составлено), Näyttökuva.pngа bash 3.2 - нет.
Lri