Підказка терміналу не завершується правильно


171

У мене виникла проблема, коли, якщо я наберу дуже довгі команди в bash, термінал не відобразить те, що я правильно вводить. Я б очікував, що якби у мене була така команда:

username@someserver ~/somepath $ ssh -i /path/to/private/key
myusername@something.someserver.com

Команда повинна відображатись у двох рядках. Натомість вона часто загортається і починає писати над моїм підказкою, приблизно так:

myreallylongusername@something.somelongserver.comh -i /path/to/private/key

Якщо я вирішу повернутися назад і змінити якийсь аргумент, там не буде сказано, де з’явиться курсор, іноді посеред підказки, але зазвичай у рядку вгорі, де я друкую.

Додаткове задоволення трапляється, коли я переходжу Upдо попередньої команди. Я спробував це як в гном-терміналі, так і в термінаторі, а також в i3 та Cinnamon. Хтось підказав, що це моє підказка, тож ось що:

\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]

Ctrll, resetі clearвсі роблять те, що вони говорять, але коли я набираю команду назад або Upвідбувається те ж саме.

Я перевірив, і checkwinsizeвін включений в bash. Це відбувається в розмірах 80x24 та інших розмірах вікон.

Це просто те, з чим я вчуся жити? Чи є якась магія, яку я повинен знати? Я вирішив просто використовувати дуже короткий підказку, але це не вирішує проблему.


1
Тож за допомогою команди env -i bash --norcвиправляє її. $ COLUMNS та $ LINES відповідають. Це означає, що з моїм .bashrc є щось смішне?
Мурікула

Тому я прокоментував свій .bashrc і завершив виділення мого підказки як проблематичну частину, зокрема синтаксис забарвлення. Що не так з PS1 вище?
Muricula

1
\[\033[01;32m\]\u: \[\033[01;34m\]\W \[\033[01;34m\] \$ \[\033[0m\]начебто уникає дивацтва в поведінці - але не знаю, чи повністю він поважає ваш оригінальний підказки ...

1
Відповідно до цієї відповіді на сервері за замовчуванням , використовуйтеtput smam
Samveen

Відповіді:


189

Послідовності, що не друкуються, повинні бути вкладені в \[та\] . Дивлячись на ваш PS1, він має незамкнену послідовність після \W. Але другий запис є зайвим, оскільки повторює попереднє твердження "1; 34" .

\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]
                  |_____________|               |_|
                         |                       |
                         +--- Let this apply to this as well.

Як такий, це повинно було передбачити забарвлення:

\[\033[1;32m\]\u:\[\033[1;34m\] \W \$\[\033[0m\]
                               |_____|
                                  |
                                  +---- Bold blue.

Зберігаючи "оригінал", це також має працювати:

\[\033[1;32m\]\u:\[\033[1;34m\] \W\[\033[1;34m\] \$\[\033[0m\]
                                  |_|         |_|
                                   |           |
                                   +-----------+-- Enclose in \[ \]

Редагувати:

Причина такої поведінки полягає в тому, що bashвважає, що підказка довша, ніж вона є насправді. Як простий приклад, якщо використовується:

PS1="\033[0;34m$"
       1 2345678

Вважається, що підказка має 8 символів, а не 1. Як таке, якщо вікно терміналу становить 20 стовпців, після введення 12 символів вважається, що це 20, і обертається навколо. Це також очевидно, якщо потім спробувати зробити backspace або Ctrl+u. Він зупиняється на колонці 9.

Однак він також не починає новий рядок, якщо один не знаходиться в останньому стовпці, в результаті перший рядок буде перезаписаний.

Якщо ви продовжуєте набирати рядок, слід перейти до наступного рядка після 32 символів.


Якщо у вас - або у когось - є пояснення щодо того, що саме в початковій послідовності викликало повторення рядка над собою, мені було б цікаво це знати. Також +1 для того, як ви це візуально показали.

1
@ iluminÉ: Не дивилися на джерело, але додали оновлення із приміткою про поведінку від спостереження.
Руніум

На всякий випадок, якщо у вас виникли якісь проблеми, ви можете скористатися цим веб-сайтом, щоб створити новий - bashrcgenerator.com
divinedragon

Це дивовижно, дякую @Runium - ти б не проти поділитися тим, як ти це знав? Я хотів би знайти трохи документації щодо цього.
nycynik

2
@nycynik: Спостереження. Я думаю, що найближчим до документації щодо цього є вихідний код ...
Руніум

83

Це пов'язано з тим, що розмір вікна, припущеного терміналом, не є таким, як ваш фактичний розмір вікна. Якщо ви використовуєте bash, ви можете спробувати це.

$ shopt checkwinsize

Якщо ви не отримаєте

checkwinsize    on

Потім активуйте його за допомогою

$ shopt -s checkwinsize

Потім просто спробуйте виконати іншу команду (наприклад ls) або змінити розмір вікна один раз, вищезазначене працює для мене кожен раз.

Особливо для систем Redhat, проблема часто викликана неправильним налаштуванням ~/.bashrcне викликати дзвінки /etc/bashrc. Як правило, bash навантажень, ~/.bashrcякі, як очікується, викликає /etc/bashrc, які за замовчуванням містять shopt -s checkwinsize.


Була така ж проблема з OS X, мабуть, якщо ви запускаєте "login", щоб запустити свій термінал, він запускає bash таким чином, що читає / etc / bashrc, але якщо ви просто зателефонуєте прямо на bash, ~ / .bashrc не робить вихідні речі за замовчуванням, щоб ви отримали незвичайний ефект обгортки. Дякую!
rogerdpack

Це працювало і для мене. На цьому конкретному сервері кольорів не було, виклик правильний /etc/bashrc, все інше було добре пройти ... Виявляється, це причина проблем із обгортанням.
dhaupin

Дивіться також unix.stackexchange.com/a/61608/2221
astrojuanlu

Виглядає як хороше рішення. Але це не працює в моєму сеансі ssh. Не знаю чому. Я запустив команду shopt -s checkwinsizeв сесії ssh. Але обгортання зберігається.
Цянь Сюй

В цьому якраз і була моя проблема - користувач .bashrc не дзвонив / etc / bashrc, і таким чином заплутався.
Sobrique

9

Як вже згадувалося в інших відповідях, такі послідовності, які не можна роздрукувати, такі, як \e[0;30mслід \[...\].

Додатково (і те, що я ще не бачу згаданого), схоже, що це \r\nповинно бути поза тим, \[...\]якщо у вас є багаторядковий запит. Мені знадобилося трохи спроб і помилок, щоб остаточно зрозуміти це.


8

Я колись десь прочитав (не знаю, де більше), що за допомогою \001і \002замість \[і \]можна вирішити цю проблему. Це зробило для мене.

До речі, визначення PS1 не повинно виглядати некрасиво.

green="\001$(tput setaf 2)\002"
blue="\001$(tput setaf 4)\002"
dim="\001$(tput dim)\002"
reset="\001$(tput sgr0)\002"

PS1="$dim[\t] " # [hh:mm:ss]
PS1+="$green\u@\h" # user@host
PS1+="$blue\w\$$reset " # workingdir$

export PS1
unset green blue dim reset

2
Мій PS1 викликає команду, яка виводить послідовності printf, викликаючи проблему ОП. Тільки це рішення вирішує проблему для мене.
RickMeasham

6

Це звучить як проблема із налаштуваннями змінної COLUMNSта LINESоточуючого середовища. Коли ви змінюєте розмір вікна, вони зазвичай встановлюються автоматично gnome-terminal (я вважаю), ви можете змусити їх встановлювати вручну, видаючи команду resize.

Приклад

Якщо я змінити розмір свого gnome-термінала до 79x17, мої змінні відобразяться так:

$ echo $COLUMNS; echo $LINES
79
17

Я можу так змусити:

$ resize
COLUMNS=79;
LINES=17;
export COLUMNS LINES;

1
Цікаво, але не допомагає.
Muricula

1
Це вирішило мою проблему, це було неправильне обгортання рядків після того, як я запустив команду "екран". Дякую!!
nukeguy

5

Щоб запобігти обгортанню, ви також можете збільшити кількість стовпців, використовуючи, наприклад,

stty columns 120

1
не дуже гарна ідея, вона жорстоко переплутала vim
Blauhirn

3

Також те ж саме може бути викликано використанням широких символів unicode (наприклад, з https://stackoverflow.com/a/34812608/1657819 ). Ось фрагмент, що спричиняє проблему (пам’ятайте про кольорові рядки $Greenта $Redправильно уникнуті ними кольори):

FancyX='\342\234\227'
Checkmark='\342\234\223'


# Add a bright white exit status for the last command
PS1="$White\$? "
# If it was successful, print a green check mark. Otherwise, print
# a red X.
if [[ $Last_Command == 0 ]]; then
    PS1+="$Green$Checkmark "
else
    PS1+="$Red$FancyX "
fi

Bash не може правильно обчислити довжину, тому найпростішим способом можна було б уникнути 2 з трьох частин цих широких символів.

FancyX='\[\342\234\]\227'
Checkmark='\[\342\234\]\223'

Має сенс. Я думаю, що баш рахує символів. Оскільки X має одну таблицю, але вона записується як 3, то потрібно додати 2 з них, щоб виправити підрахунок. Відповідь @blauhirn також пояснює, як робити у функції з \001і \002.
акостадінов

FYI, це те , як ви зрозуміти, як виводити багатобайтові символи Юнікоду в цьому форматі: stackoverflow.com/a/602924/520567
akostadinov
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.