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/340297COL
переменная содержит текущий столбец, в котором находится курсор. Если$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.