Как правильно избежать символов unicode в приглашении bash

у меня есть конкретный метод для моего приглашения bash, скажем, это выглядит так:

CHAR="༇ "
my_function="
    prompt=" [$CHAR]"
    echo -e $prompt"

PS1="$(${my_function}) $ "

чтобы объяснить вышеизложенное, я строю приглашение bash, выполняя функцию, хранящуюся в строке, которая была решением, принятым в результате этот вопрос. Давайте притворимся, что он работает нормально, потому что это так, за исключением случаев, когда задействованы символы unicode

Я пытаюсь найти правильный способ избежать символа Юникода, потому что прямо сейчас он путается с длина линии bash. Простой способ проверить, если он сломан, это ввести длинную команду, выполнить ее, нажмите CTRL-R и введите, чтобы найти ее, а затем нажмите CTRL-A CTRL-E, чтобы перейти к началу / концу строки. Если текст искажается, он не работает.

Я пробовал несколько вещей, чтобы правильно избежать символа юникода в строке функции, но ничего не работает.

специальные символы, такие как эта работа:

COLOR_BLUE=$(tput sgr0 && tput setaf 6)

my_function="
    prompt="[$COLOR_BLUE] "
    echo -e $prompt"

что является основной причиной Я сделал приглашение строкой функции. Эта escape-последовательность не влияет на длину строки, это просто символ Юникода.

3 ответов


на \[...\] sequence говорит полностью игнорировать эту часть строки, что полезно, когда ваше приглашение содержит последовательность нулевой длины, такую как управляющая последовательность, которая изменяет цвет текста или строку заголовка, скажем. Но в этом случае вы печатаете символ, поэтому длина его не равна нулю. Возможно, вы могли бы обойти это, скажем, используя последовательность побега no-op, чтобы обмануть Bash в вычислении правильной длины линии, но похоже, что это ложь сумасшествие.

правильным решением было бы для расчетов длины линии в Bash правильно grok UTF-8 (или какая бы кодировка Unicode вы ни использовали). Вы пробовали без \[...\] последовательности?

Edit: следующая реализует решение, которое я предлагаю в комментариях ниже. Положение курсора сохраняется, затем печатаются два пробела вне \[...\], затем восстанавливается положение курсора и печатается символ Юникода на вершине двух пространств. Это предполагает фиксированную ширину шрифта с двойной шириной для символа Юникода.

PS1='\['"`tput sc`"'\]  \['"`tput rc`"'༇ \] $ '

по крайней мере, в терминале OSX, Bash 3.2.17(1)-release, это проходит поверхностное тестирование [sic].

в интересах прозрачности и удобочитаемости я проигнорировал требование иметь функциональность приглашения внутри функции и цветовое кодирование; это просто изменяет приглашение на символ, пространство, приглашение доллара, пространство. Адаптироваться к несколько костюм ваш более сложные потребности.


@tripleee выигрывает его, публикуя окончательное решение здесь, потому что это сука, чтобы опубликовать код в комментариях:

CHAR="༇"
my_function="
    prompt=\" \[`tput sc`\]  \[`tput rc`\]\[$CHAR\] \"
    echo -e $prompt"

PS1="$(${my_function}) $ "

трюк как указано в ссылке tripleee является использование команды tput sc и tput rc которые сохраняют, а затем восстанавливают положение курсора. Код эффективно сохраняет позицию курсора, печатая два пробела для ширины, восстанавливая позицию курсора перед пробелами, а затем печатая специальный символ так, чтобы ширина строки была из двух пробелы, а не характер.


(не ответ на вашу проблему, но некоторые указатели и общий опыт, связанные с вашей проблемой.)

Я вижу поведение, которое вы описываете о редактировании cmd-line (Ctrl-R, ... Cntrl-A Ctrl-E...) все время, даже без символов unicode.

на одном рабочем месте я потратил время, чтобы выяснить разницу между интерпретацией терминалов термина настройки против определения термина, используемого ОС (ну, я полагаю, stty).

теперь, когда у меня есть это проблема, я выхожу из своей текущей попытки отредактировать строку, снова подвести строку, а затем сразу перейти в режим "vi", который открывает редактор vi. (нажмите только символ "v", правильно?). Вся простота использования полноценной сессии vi; зачем идти с меньшим ; -)?

снова глядя на описание вашей проблемы, когда вы говорите

my_function="
    prompt=\" \[$CHAR\]\"
    echo -e $prompt"

это просто определение, верно? и я предполагаю, что вы упрощаете определение проблемы, предполагая, что это результат ваш my_function. Кажется очень вероятным, что на этапах создания определения функции, вызова функции и использования возвращаемых значений есть много возможностей для цитирования оболочки, чтобы не работать так, как вы хотите.

если вы отредактируете свой вопрос, чтобы включить my_function определение и его полное использование (сокращение вашей функции до того, что вызывает проблему), другим может быть легче помочь в этом тоже. Наконец, вы используете set -vx регулярно? Это может помочь показать как/wnen / что из переменных расширений, вы можете найти что-то там.

не все из них, посмотрите на Orielly termcap & terminfo. Возможно, Вам понадобится посмотреть man-страницу для ваших локальных систем stty и связанные cmds, и вы можете хорошо искать группы пользователей, специфичные для вас Linux-системы (я предполагаю, что вы используете вариант Linux).

надеюсь, это поможет.