My terminal theme used to be like this,

terminal them before

But I thought the prompt wasted so much space. And later I got an idea that I could clean the prompt every time I ran a command. I was using bash, one of solution is to use the preexec_invoke_exec function.

I use the following command to clean the last prompt chars:

echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"

So that the terminal is very clean, like this,

enter image description here

But now my problem is, there will be problem if I want to use multi commands in one line, say, when I use for i in ....

Here is the full version of the function in my .bashrc,

preexec () { echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"; echo -n "$1"; echo -ne "  \033[37;2m["; echo -n "$2"; echo -ne "]\033[0m\n"; }
preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`; 
    preexec "$this_command" "$this_pwd"
trap 'preexec_invoke_exec' DEBUG
  • The Glyph Lefkowitz zsh trick - nice! – user44370 Dec 30 '13 at 14:34
  • 2
    The easy solution starts with zsh – Gilles 'SO- stop being evil' Dec 30 '13 at 22:45
  • I missed your question in there... – David Hoelzer Feb 4 '14 at 23:39
  • @DavidHoelzer Well if you do for i in $(seq 1 10); do ls; done with his function, the output of the iterating commands gets "swallowed" so to speak. So OP wanted to sanitize the behavior while enabling that prompt. The reason why I support this is interest for awareness in the shell, usability, feedback and portability. The link I had put in my prior comment leads to the post on superuser - they went to the trouble of attributing this snippet, so it's a prototype which emulates native zsh functionality (which I think is interesting), in the form of a trap function here. – user44370 Feb 5 '14 at 3:10

First preexec_invoke_exec has to be modified to prevent multiple executions of preexec. Also, modify preexec to take in account the actual number of lines in $PS1 :

preexec () { 
    # delete old prompt; one "\e[1A\e[K" per line of $PS1
    for (( i=0, l=$(echo -e $PS1 | wc -l) ; i < l ; i++ ))
        echo -ne "\e[1A\e[K"
    # replacement for prompt
    echo -ne "\e[31;1m$ \e[0m"
    echo -n "$1"
    echo -ne "  \e[37;2m["
    echo -n "$2"
    echo -e "]\e[0m"

preexec_invoke_exec () {
    [ -n "$DONTCLEANPROMPT" ] && return
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`
    preexec "$this_command" "$this_pwd"

trap 'preexec_invoke_exec' DEBUG


In order for preexec to be run again, DONTCLEANPROMPT has to be either unset or set to ''. This is done with PROMPT_COMMAND, which is run just before the primary prompt is issued. Therefore preexec will be run once and only once for every command line.

| improve this answer | |
  • Your solution solves the issue with the for loop! Thank you! There is a further inconvenience. What happens is that if you do ls on the command and you have the output, then you do another ls, you will see that the last line of the prior output gets erased... do you have an idea how to resolve that? – user44370 Feb 10 '14 at 3:01
  • 1
    You are probably using a prompt with only a single line. Change the first echo in prexec to print "\033[1A\033[K\033[31;1m$ \033[0m", that is only one \033[1A\033[K (move 1 line up, delete till end of line) instead of two. – Adaephon Feb 10 '14 at 10:02
  • Flawless! Thank you very much for your solution and taking the time to explain. This solves OP's problem and debugs the solution even further. Makes it usable for everyone! Cheers! – user44370 Feb 11 '14 at 6:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.