Как правильно избежать символов 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).
надеюсь, это поможет.