Переход назад в командной строке bash

Я хотел бы иметь пустую строку после приглашения bash и перед выводом на моем Mac. Это должно выглядеть так:

echo; ls

Могу ли я добавить новую строку в мое приглашение bash, а затем вернуться на одну строку назад, чтобы дождаться ввода пользователя? Есть ли что-то очевидное, что мне не хватает?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
0
5 713
7

Ответы 7

Насколько мне известно, это невозможно, если вы не углубитесь в более низкоуровневые вещи, такие как полноэкранные эмуляторы, такие как проклятия.

Это немного укол в темноте, но вы, май, сможете использовать Коды клемм VT102 для управления курсором без использования Curses. Все соответствующие команды VT102, которые могут вас заинтересовать, состоят из отправки ESC, затем [, затем конкретных параметров команды.

Например, чтобы переместить курсор на одну строку вверх, нужно вывести:

ESC  [    1    A
0x1B 0x5B 0x31 0x41

Имейте в виду, что в документации VT102 обычно используется восьмеричное число, поэтому держите таблица ascii под рукой, если вы используете шестнадцатеричный.

Все эти советы даются без тестирования - я не знаю, можно ли встраивать команды VT102 в ваше приглашение bash, но я подумал, что стоит попробовать.

Обновлено: Да - похоже, что много людей использует коды форматирования VT102 в своих приглашениях bash. Чтобы перевести мой приведенный выше пример во что-то, что Bash распознал бы, поместив:

\e[1A

в командной строке следует переместить курсор на одну строку вверх.

Вы можете перемещаться вверх и вниз по приглашению сколько угодно, но к тому времени, когда он успокоится для ввода, первый вывод будет в строке непосредственно под курсором, который ранее находился в строке, где был конец приглашения. и где пользователь ввел команду. Таким образом, перед выводом не будет пустой строки.

Dennis Williamson 03.08.2010 04:13

Я считаю (но не пробовал), если вы поместите '\n\b' в строку приглашения, он сделает это.

Это вполне возможно. Если в вашем bash C-v установлен как команда readline quoted-insert, вы можете просто добавить в свой ~/.inputrc следующее:

RETURN: "\C-e\C-v\n\C-v\n\n"

Это заставит bash (фактически, readline) вставить два дословных символа новой строки перед обычным интерпретируемым символом новой строки. По умолчанию вставляется только один, поэтому вывод начинается со строки после приглашения.

Вы можете проверить, установлен ли C-v на цитируемую вставку, набрав его в bash (это Ctrl+V), а затем, например, стрелка вверх. Это должно напечатать ^[[A или что-то подобное. Если этого не произойдет, вы также можете привязать его к ~/.inputrc:

C-v: quoted-insert
RETURN: "\C-e\C-v\n\C-v\n\n"

~/.inputrc можно создать, если он не существует. Изменения не вступят в силу при запуске аварийных сообщений, если вы не введете команду readline re-read-init-file (по умолчанию на C-x C-r). Но будьте осторожны. Если вы сделаете что-то не так, Enter больше не будет выдавать команды, и исправить ошибку может оказаться непросто. Если вы сделаете что-то не так, C-o по умолчанию также примет эту строку.

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

Это не сработает, если курсор находится не в конце строки. Попробуйте: RETURN: "\C-e\C-v\n\C-v\n\n", который отправляет курсор в конец строки, а затем добавляет дополнительные строки. Однако всегда печатается дополнительная строка новой строки, даже если вы нажмете Enter в пустом приглашении.

Dennis Williamson 03.08.2010 04:07

Не могли бы вы объяснить, почему это работает? AFAIU, два заключенных в кавычки курсора новой строки и последний (не заключенный в кавычки) делают readline завершающим чтение пользовательского ввода. Но почему он сам по себе не печатает лишнюю новую строку?

x-yuri 06.12.2012 23:50

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

В этом случае код курсор вверх на одну строку можно определить по:

tput cuu1

Если вы перенаправите вывод tput в файл, вы увидите, какие управляющие символы используются.

Bash также поддерживает переменную PROMPT_COMMAND, позволяющую запускать произвольные команды перед каждым запросом.

Это работает:

trap echo DEBUG

Он не добавляет лишнюю новую строку, если вы нажимаете return в пустом приглашении.

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

$ echo foo; echo bar
\n
foo
\n
bar

Чтобы предотвратить это, чтобы перед выводом всей команды выводилась только одна дополнительная строка:

PROMPT_COMMAND='_nl=true'; trap -- '$_nl && [[ $BASH_COMMAND != $PROMPT_COMMAND ]] && echo; _nl=false' DEBUG

Прерывание DEBUG выполняется перед каждой командой, поэтому перед первой командой он проверяет, является ли флаг истинным, и, если да, выводит новую строку. Затем он устанавливает флаг в значение false, чтобы каждая последующая команда в строке не запускала дополнительный перевод строки.

Содержимое $PROMPT_COMMAND выполняется до вывода подсказки, поэтому для флага установлено значение «истина» - готовность к следующему циклу.

Поскольку нажатие Enter в пустой командной строке по-прежнему запускает выполнение содержимого $PROMPT_COMMAND, тест в ловушке также проверяет это содержимое как текущую команду и не выполняет echo, если они совпадают.

Есть ли способ сделать так, чтобы это не отображало лишние символы новой строки, если команда сложная (например, echo 5 | cat будет печатать \n\n5\n вместо желаемого \n5\n)?

Max Nanasy 04.08.2013 00:45

@MaxNanasy: PROMPT_COMMAND='_nl=true'; trap -- '$_nl && [[ $BASH_COMMAND != _nl=true ]] && echo; _nl=false' DEBUG вызовет вывод только одной новой строки, независимо от того, сколько элементов находится в конвейере.

Dennis Williamson 04.08.2013 02:10

@MaxNanasy: см. Мой отредактированный ответ для объяснения и улучшенной версии по сравнению с тем, что в моем комментарии выше.

Dennis Williamson 04.08.2013 02:23

Спасибо: это помогло предотвратить дублирование новой строки, хотя также предотвратило отображение новой строки после команды (что и делала старая версия); Я исправил это, добавив новую строку в начале $ PS1.

Max Nanasy 04.08.2013 03:34

Я знаю, что это устарело, но для кого-то вроде меня, кто наткнулся на это во время поиска в Google. Вот как вы это делаете ... На самом деле это довольно просто!

Посмотрите эту ссылку -> Движение курсора

В основном, чтобы переместиться на N строк:

echo -e "\033[<N>A HELLO WORLD\n"

Просто измените "<N>" на любое количество строк, на которое вы хотите вернуться ... Например, чтобы переместиться на 5 строк вверх, это будет "/ 033 [5A".

Другие вопросы по теме