Як змусити довгі командні рядки перейти до наступного рядка?


108

Щось я помітив в Ubuntu вже давно, що мене засмучує, - це коли я набираю команду в командному рядку, який стає довшим (ширшим), ніж ширина терміналу, замість того, щоб переходити на новий рядок, він повертається до стовпець 1 в тому ж рядку і починає надписувати початок мого командного рядка. (Він фактично не перезаписує фактичну команду, але візуально це перезапис тексту, який відображався).

Важко пояснити, не бачачи цього, але скажімо, що мій термінал був шириною 20 символів (Шахта більше схожа на 120 символів - але заради прикладу), і я хочу повторити англійський алфавіт. Що я набираю, це:

echo abcdefghijklmnopqrstuvwxyz

Але як виглядає мій термінал, перш ніж натиснути ключ, це:

pqrstuvwxyzghijklmno

Коли я натиснув Enter, це лунає луною

abcdefghijklmnopqrstuvwxyz

тому я знаю, що команда отримана належним чином. Він просто завершив моє друкування після "o" і почав знову на тій же лінії.

Що я б очікував, що станеться, якби я набрав цю команду на терміналі, шириною всього 20 символів, це було б:

echo abcdefghijklmno
pqrstuvwxyz

Передумови: я використовую bash як свою оболонку, і цей рядок є у моєму ~ / .bashrc:

set -o vi

мати можливість переміщатися в командному рядку за допомогою команд VI. Зараз я використовую сервер Ubuntu 10.10 і підключаюсь до сервера за допомогою Putty.

У будь-якому іншому середовищі, в якому я працював, якщо я введу довгий командний рядок, він додасть новий рядок під рядком, над яким я працюю, коли моя команда стає довшою за ширину терміналу і коли я продовжую вводити текст, я можу побачити свою команду на 2 різні лінії. Але поки я можу запам'ятати використання Ubuntu, мої довгі команди займають лише 1 рядок.

Це також відбувається, коли я повертаюсь до попередніх команд в історії (натискаю Esc, потім 'K', щоб повернутися до попередніх команд) - коли я переходжу до попередньої команди, яка була довшою за ширину терміналу, командний рядок отримує розгублений, і я не можу сказати, де я в команді.

Єдина обробка, яку я знайшов, побачивши всю довгу команду, - це натиснути "Esc-V", що відкриває поточну команду в редакторі VI.

Я не думаю, що у мене є .bashrc файл. Я прокоментував лінію "set -o vi", і в мене все-таки виникли проблеми.

Я завантажив нову копію Putty і не вніс жодних змін у конфігурацію - я просто набрав своє ім’я хоста, щоб підключитися, і у мене все ще є проблема, тому я не думаю, що це нічого з Putty (якщо мені не потрібно внести деякі зміни конфігурації)

Хтось ще мав цю проблему, і хтось може подумати, як її виправити?

Редагувати

Це був мій файл .bashrc. Я скопіював один і той же профіль з машини на машину, і я використав спеціальні символи в моєму $ PS1, які якимось чином скидають його. Тепер я дотримуюся стандартних змінних bash для мого PS1 $.

Дякуємо @ ændrük за підказку на .bashrc!

... Закінчити редагування ...


1
Щоб переконатися, що проблема не викликана вашим файлом .bashrc, рекомендую тимчасово замінити її на копію /etc/skel/.bashrc. Майте на увазі, що вам потрібно буде знову підключитися, щоб зміни набули чинності, і не забудьте зберегти резервну копію власного .bashrc.
ændrük

1
Який термінальний додаток ви використовуєте? Поведінка, яку ви описуєте, не є звичайною, звичайно не є типовою.
Жоао Пінто

У оболонках, в яких я працював (і в Cisco CLI), ви також можете ввести Ctrl-L, щоб повторно відобразити лінію, яку ви вводите, навіть якщо вона є поза екраном. У вашій ситуації це все-таки може призвести до непрацюючого результату, про який ви говорите, але мені буде цікаво.
belacqua

3
Сміливо створіть "відповідь", що пояснює рішення, і позначте його як прийняте. Це може здатися трохи нерозумним, але правильна відповідь допомагає організовувати сайт і може ефективніше керувати іншими, у кого подібні проблеми в майбутньому.
ændrük

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

Відповіді:


136

Переконайтеся, що всі недрукувані байти у вашому PS1 містяться в ньому \[ \]. В іншому випадку bash буде рахувати їх по довжині підказки. Він використовує довжину підказки, щоб визначити, коли обернути лінію.

Наприклад, тут bash вважає підказку шириною 19 стовпців, тоді як підказка, що відображається терміналом, становить лише 10 стовпців ( My promptнаписана блакитним >кольором та написана кольором за замовчуванням):

PS1='\e[36mMy prompt\e[0m>'         # bash count: 19, actual: 10

в той час як тут він вважає лише запит шириною 10 стовпців, оскільки він ігнорує байти між спеціальними \[і \]уникає:

PS1='\[\e[36m\]My prompt\[\e[0m\]>' # bash count: 10, actual: 10

Для належної практики, використовуйте tputдля створення термінальних втеч, а не жорсткого їх кодування:

cyan=$(tput setaf 6) # \e[36m
reset=$(tput sgr0)   # \e[0m
PS1='\[$cyan\]My prompt\[$reset\]>'

Дивіться http://mywiki.wooledge.org/BashFAQ/053 , а також http://wiki.bash-hackers.org/scripting/terminalcodes для отримання додаткової інформації про tput.


3
Це чудове пояснення проблеми, на яку не вказує прийнята відповідь
Джеймі Кук

В останньому рядку коду PS1='...': чому окремі лапки не запобігають $cyanта $resetне замінюють?
andrybak

2
@andrybak, вони перешкоджають заміні $cyanта $resetзаміні, але PS1оцінюються щоразу, коли надруковано запит. Ви можете переконатись у цьому, спробувавши, PS1='$var> 'а потім надати varрізні значення та побачити, як змінюється підказка. Потім спробуйте PS1="$var> " помітити, що запит залишається статичним; $varотримали розширення під час виконання завдань, але не кожен раз PS1оцінюються.
geirha

1
Це дивно. Велике спасибі за публікацію! Це робить втечу з квадратних дужок набагато простішим і легшим для читання.
фіат

Як я роблю цю роботу PS1=${PS1}"\e]2;$@\a". Я спробувавPS1=${PS1}"\[\e]2;\]$@\[\a\]"
Рамана Редді

59

Я думаю, ви налаштували свої PS1кольори, правда?

Просто переконайтеся , що у вас є \[у вашій PS1цитаті попереднього свого набір кольору

Наприклад:

PS1='\[\e[0;32m\u@\w/:\[\e[m '

Мій PS1 був export PS1='^[[96m'$(hostname)'<^[[92m${PWD}^[[96m>^[[97m '- я давно його використовую - він сумісний із KSH ...
BrianH

2
Ого. Я використовую підказки терміналів з тих пір і ніколи раніше не мав цієї проблеми. Ніколи б не зрозумів цього. Дякую.
bchurchill

3
використання \ [при використанні простих лапок дає непередбачувану косу рису. також, їх слід використати] в кінці магічних ознак, як зазначено у найкращій відповіді
igorsantos07

2
-1 Не працює. Вам потрібно обернути недрукарський розділ \[на початку та \]в кінці.
wjandrea

@ igorsantos07 Подвійний зворотний косий рядок \\[був помилковим помилкою, викликаним редагуванням. Я це виправив.
wjandrea

11

У мене було подібне питання, і нарешті знайшли просте рішення.

Додайте у свій .bashrcфайл наступний рядок :

COLUMNS=250

Потім введіть, source ~/.bashrcщоб отримати бажаний ефект.


У деяких випадках, таких як вузькі підрозділи термінатора, проблема полягає не в кольорі символів прома, а лише в неправильному значенні КОЛУНС. Ця відповідь вивела мене з дуже набридливої ​​діри!
Карлес Сала

1
Вихід із системи непотрібний. Зробіть source .bashrc. Ваше повідомлення буде оновлено негайно
Сергій Колодяжний

1
Я виявив, що оскільки я не робив setwinsizeнабір для свого башма, тому це не було оновлення COLUMNS вправо, див. Unix.stackexchange.com/a/167911/8337
rogerdpack

1
Я export COLUMNS=250пішов за ним, export TERM=xtermі це було щасливо.
Філіп Кірнс

5

У мене була така ж проблема із користувацьким кольоровим підказкою, хоча я містив коди кольорів усередині \[та \]роздільники. Виявляється, у баша є проблеми, що перегукуються з кольорами всередині функції . Я в кінцевому підсумку просто використовував змінні для мого підказки, і хоч мій .bashrc трохи менш елегантний, зараз усе добре працює.


Якщо хтось все ще читає це, насправді можливо уникнути кольорів у функції. Дивіться цю відповідь на пов'язане питання.
wjandrea

3

Просту річ було б додати наступний рядок перед встановленням PS1:

stty columns 1000

Наприклад,

stty columns 1000
PS1='\[\e[0;32m\u@\w/:[\e[m '

однак це впливає на інші команди Unix, такі як ls і man.


1
Це працює в OSX.
raskhadafi

4
Це також погано впливає на vim. Будь ласка, не використовуйте це.
justhalf

0

У мене була ця проблема під час підключення в tmux. Проблема полягала в тому, що я мав ipythonсеанс у фоновому режимі ( ctrl + z) і що якимось чином порушив обгортання ліній. Як тільки я його припинив ( fg, ctrl+d+d) мій термінал почав працювати належним чином

Тому перевірте наявність зупинених інтерактивних підказок.


0

Тож у мене було те саме питання з невеликим поворотом на ньому, і я думав, що поділюсь своїм рішенням, просто щоб додати свій маленький нюанс: D

Мій початковий PS1 був

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$"

Проблема в мене полягала в тому, що я намагався змінити назву термінала , а також командний рядок. Те , як я зробив це, додавши \[\033]0;\]Title\aдо PS1 змінної.

Тож тепер мій PS1:

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[\033]0;\]Title\a"

Це переплутало обертання лінії для мене. Нарешті я зрозумів, що баш, схоже, не подобається \aв кінці. Щоб обійти це, я помістив заголовок у змінну, яка, здавалося, виправила його.

TITLE="\033]0;Title\a"
PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[$TITLE\]"

0

\[і \]не працювали для мене. Напевно, було щось інше в тому, як я генерував підказку (із зовнішньої програми) або тому, що мій підказки був "динамічним".

Після прочитання цього я виявив , що ви можете уникнути колірних кодів з 0x01і 0x02байтів.

наприклад, я використовую спеціальну версію крейди і обертаю кольори за допомогою цього:

const Chalk = require('@nasc/chalk');

const chalk = new Chalk.constructor({
  wrapper: {
    pre: '\1',
    post: '\2',
  }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.