No theme, no regular posting.


© 2014-2023. Raphaël Rigo CC-BY-SA 4.0


Adding a newline when necessary to bash's prompt

The problem

Since years I’ve raged when my cursor in my bash prompt was incoherent: the blinking rectangle was in one place but deleting chars would delete the wrong ones.

I finally took the time to try to understand what was wrong. Long story short: if the previous command did no end with a newline.

A typical case is when using curl, which by default, outputs the page without adding a newline at the end. But a simple way to reproduce is to use echo:

trou@valhalla:~$ echo -n test

But the problem is that it’s not bash’s role to check the output of the last command. Some “modern” shells such as zsh or fish actually do that. But I wanted to find a solution which works everywhere, and bash is the common denominator for most Linux and Unix systems.

How to fix?

I first found a solution which involved writing spaces until the line wraps, but it broke when using a python virtualenv.

The answer on this StackExchange question is actually quite clever: is reads the current cursor position using terminal escape codes and only outputs a newline if we are not in the first column.

The final result for me is:

PS1='${debian_chroot:+($debian_chroot)}\[\e[38;5;111m\]\u@\[\e[92m\]\h\[\e[39m\]$text:\[\e[38;5;86m\]\w\[\e[00m\]\$ '

new_line_ps1() {
  local _ y x _
  local RESET="\001\e[0m\002"

  IFS='[;' read -p $'\e[6n' -d R -rs _ y x _
  if [[ "$x" != 1 ]]; then
    printf "\n${RESET}"

Midnight Commander

One last thing to fix is to avoid mc weird behaviour (slooooow start) when running with this PS1, by actually disabling the functionnality when running under mc:

# Don't add newline in mc
if [ -z $MC_SID ]; then

Fish also had a problem, which they workedaround with the exact same if.