Bash: как узнать, заканчивается ли вывод последней команды переводом строки или нет?

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

Пример:

root @ hostname [~] # echo -n hello
helloroot @ hostname [~] #

Я всегда находил это очень раздражающим.
Теперь я мог бы просто добавить "\n" в начале переменной PS1, но большую часть времени это будет выводить одну лишнюю строку, которая мне не нужна.

Можно ли узнать, закончился ли вывод последней команды новой строкой или нет?


Решение:
(Спасибо Деннису)

PS1='$(printf "%$((`tput cols`-1))s\r")\u@\h [\w]\$ '

4 ответа

Решение

Я экспериментировал со следующим, чтобы подражать zsh в Баш:

$ unset PROMPT_SP; for ((i = 1; i <= $COLUMNS + 52; i++ )); do PROMPT_SP+=' '; done
$ PS1='\[\e[7m%\e[m\]${PROMPT_SP: -$COLUMNS+1}\015$ '

Он выдает обратный видео знак процента, за которым следует куча пробелов, чтобы перенести его на следующую строку, затем возврат каретки, затем знак доллара и пробел. Вы можете добавить экранирование подсказки после "\015", чтобы настроить подсказку.

Использование этого зависит от того, как ваш терминал обрабатывает перенос правой строки поля (автоматические поля). Длина PROMPT_SP произвольна, но должна быть не менее 80 или любой другой ширины вашего терминала. Возможно, вам придется жестко закодировать это значение, если $COLUMNS еще не установлено к тому времени, когда for цикл запускается в ~/.bashrc, Вы можете хотеть shopt -s checkwinsize если это еще не установлено.

zsh пытается решить вашу проблему. Если последний вывод заканчивается без новой строки, вы получите:

$ echo -n 'abc'
abc%
$ 

Где % использует перевернутый фон / передний план. Не уверен, что это портативный bash в любом случае.

Нет, это невозможно. Сам Bash не обрабатывает и не видит вывод программы, которую он запустил.

Мне просто пришло в голову, что можно написать программу для установки PROMPT_COMMAND to, которая проверяет текущую позицию курсора и выдает новую строку, если курсор не находится на левом краю.

Я получил эту идею от @Teddy об обнаружении горизонтального положения курсора и выводе новой строки, если ее нет в первом столбце.

В bash мы можем определить положение курсора с помощью этой команды:IFS=';' read -sdR -p $'\E[6n' ROW COL. Дополнительная информация в этом ответе: https://unix.stackexchange.com/a/183121/340297
COLпеременная содержит текущий столбец, в котором находится курсор. Если$COLне равно 1, добавьте новую строку перед установкой переменной PS1.

Вот моя реализация:

      _set_prompt() {
    IFS=';' read -sdR -p $'\E[6n' ROW COL # Get cursor position
    [ $COL -ne 1 ] && echo '' # Add newline if cursor is not at 1st column
    PS1="........." # Your PS1 variable
}

PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'_set_prompt'

И вот результат (с разными PS1):

echo -nне включает новую строку, но новая строка выдается перед отображением приглашения. Принимая во внимание, что дополнительной новой строки нет, если новая строка уже напечатана обычной командой echo.

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