How to start XTerm with prompt at the bottom?

If using bash, the following should do the trick:

TOLASTLINE=$(tput cup "$LINES")
PS1="\[$TOLASTLINE\]$PS1"

Or (less efficient as it runs one tput command before each prompt, but works after the terminal window has been resized):

PS1='\[$(tput cup "$LINES")\]'$PS1

To prevent tput from changing the exit code, you can explicitly save and reset it:

PS1='\[$(retval=$?;tput cup "$LINES";exit $retval)\]'$PS1

Note that the variable retval is local; it doesn't affect any retval variable you might have defined otherwise in the shell.

Since most terminals cup capability is the same \e[y;xH, you could also hardcode it:

PS1='\[\e[$LINES;1H\]'$PS1

If you want it to be safe against later resetting of PS1, you can also utilize the PROMPT_COMMAND variable. If set, it is run as command before the prompt is output. So the effect can also be achieved by

PROMPT_COMMAND='(retval=$?;tput cup "$LINES";exit $retval)'

Of course, while resetting PS1 won't affect this, some other software might also change PROMPT_COMMAND.


As a slight simplification to the previous answer, I found it easier to just run:

tput cup $LINES

in the beginning of .bashrc or .zshrc. It just does the job.

Pros:

  • it only prints once, when you start your shell

Cons:

  • when clearing screen with ^L, it doesn't print and aliasing clear to clear; tput ... doesn't help;
  • prompt moves elsewhere when terminal is resized

The answers using $LINES are unnecessarily non-portable. As done in resize, you can simply ask xterm to set the position to an arbitrarily large line number, e.g.,

tput cup 9999 0

(assuming that you have a window smaller than 10 thousand lines, disregarding scrollback).

Because the string will not change as a side-effect of resizing the window, you can compute this once, and paste it into your prompt-string as a constant, e.g.,

TPUT_END=$(tput cup 9999 0)

and later

PS1="${TPUT_END} myprompt: "

according to your preferences.

As for other processes modifying PS1: you will have to recompute PS1 after those changes, to ensure that it looks as you want. But there's not enough detail in the question to point out where to make the changes.

And finally: the behavior for tab-completion doesn't mesh with this sort of change, due to bash's assumptions.