Как мне получить длинные командные строки для переноса на следующую строку?

Что-то, что я заметил в Ubuntu в течение долгого времени, что меня расстраивало, - это когда я набираю команду в командной строке, которая становится длиннее (шире), чем ширина терминала, вместо переноса на новую строку, она возвращается к столбцу 1 в той же строке и начинается заново -пишу начало моей командной строки. (На самом деле он не перезаписывает фактическую команду, но визуально он перезаписывает текст, который был отображен).

Это трудно объяснить, не видя этого, но, допустим, ширина моего терминала составляла 20 символов (мой больше похож на 120 символов - но для примера), и я хочу повторить английский алфавит. То, что я печатаю, это:

echo abcdefghijklmnopqrstuvwxyz

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

pqrstuvwxyzghijklmno

Когда я нажимаю enter, он отзывается эхом

abcdefghijklmnopqrstuvwxyz

так что я знаю, что команда была получена правильно. Он просто завернул мой ввод после буквы "о" и начал заново с той же строки.

То, что я ожидал бы, если бы я ввел эту команду на терминале, ширина которого составляла всего 20 символов, было бы следующим:

echo abcdefghijklmnopqrstuvwxyz

Предыстория: Я использую 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!

...Завершите редактирование...

Убедитесь, что все непечатаемые байты в вашем 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[36mreset=$(tput sgr0)   # \e[0mPS1='\[$cyan\]My prompt\[$reset\]>'

Видеть http://mywiki .wooledge.org/BashFAQ/053, а также http://wiki.bash-hackers.org/scripting/terminalcodes для получения дополнительной информации о tput.

Я предполагаю, что вы настроили свой PS1 с цветами, верно?

Просто убедитесь, что у вас есть \[ внутри твоего PS1 цитата, предшествующая вашему набору цветов

Например:

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

У меня была похожая проблема, и я, наконец, нашел простое решение.

Добавьте следующую строку в свой .bashrc файл:

COLUMNS=250

Затем введите source ~/.bashrc чтобы получить желаемый эффект.

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

Проще всего было бы добавить следующую строку перед установкой PS1:

stty columns 1000

Например,

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

однако это влияет на другие команды unix, такие как ls и man.

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

Поэтому проверьте, нет ли каких-либо остановленных интерактивных подсказок.

Так что у меня просто была та же проблема с небольшим твист об этом, и я подумал, что тоже поделюсь своим решением, просто чтобы добавить свой маленький нюанс : 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\]"

\[ и \] у меня это не сработало. Я предполагаю, что было что-то другое в том, как я генерировал приглашение (из внешней программы), или потому, что мое приглашение было "динамическим".

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

например, я использую специальную версию Мел и я оборачиваю цвета, используя это:

const Chalk = require('@nasc/chalk');const chalk = new Chalk.constructor({  wrapper: {    pre: '\1',    post: '\2',  }});

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

Просто чтобы убедиться, что проблема не вызвана вашим файлом .bashrc, я бы рекомендовал временно заменить его копией /etc/skel/.bashrc. Имейте в виду, что вам потребуется повторно подключиться, чтобы изменения вступили в силу, и обязательно сохраните резервную копию вашего собственного файла .bashrc.

Какое приложение терминала вы используете? Поведение, которое вы описываете, не является обычным, и уж точно не является стандартным.

В оболочках, в которых я работал (и в Cisco CLI), вы также можете ввести Ctrl-L для повторного отображения вводимой строки, даже если она находится за кадром. В вашей ситуации это все равно может привести к нарушению вывода, о котором вы говорите, но мне было бы любопытно.

Согласно этому ответу на serverfault, используйте tput smam