bash - How can I limit the number of directories in my prompt?

05
2013-12
  • michael

    On my Mac OS X 10.6, I have my prompt set to

    PS1='\[\033[01;32m\][\w\[\033[00m\]\[\033[01;34m\]$(__git_ps1 " (%s)")\033[01;32m\]]\[\033[00m\]\$ '
    

    How can I limit the number of directories in my prompt? The \w part?

    This is because when I go deep in a directory tree, the prompt takes up the whole width of the terminal.

  • Answers
  • Karsten S.

    you already use a function in your prompt for your git branch name probably, which is nice, so just do the same for your path:

    # shorten a path in $1 to max of $2 characters, prepending a "..."
    function __shortpath {
        if [[ ${#1} -gt $2 ]]; then
            len=$2+3
            echo "..."${1: -$len}
        else
            echo $1
        fi
    }
    PS1='\[\033[01;32m\][$(__shortpath "\w" 50)\[\033[00m\]\[\033[01;34m\]$(__git_ps1 " (%s)")\033[01;32m\]]\[\033[00m\]\$ '
    

    It will limit the path to the last 50 character. This is an example. You could also think of cutting off only at a slash, but that make it more difficult.

    # drops first portion of a path $1 if length is greater than $2
    function __droppath {
        if [[ ${#1} -gt $2 ]]; then
            p=$1
            while [ ${#p} -gt $2 ]; do
                p="/"$(echo "$p"|cut -d"/" -f3-)
            done
            echo "..."$p
        else
            echo $1
        fi
    }
    PS1='\[\033[01;32m\][$(__droppath "\w" 50)\[\033[00m\]\[\033[01;34m\]$(__git_ps1 " (%s)")\033[01;32m\]]\[\033[00m\]\$ '
    

    Maybe it's also a good idea to secure the while loop by checking if new length is shorter than old length (otherwise quit) or if new length is 0 in which case you may return the last value of $p - or continue with __shortpath.

  • Rich Homolka

    I personally don't have any paths in my prompt, I don't like how it moves the prompt location, even if it's cut down.

    I put the current location in the title bar:

    USER=$(/usr/bin/id -un)
    HOSTNAME=$(uname -n)
    HOSTNAME=${HOSTNAME%%.*}
    PROMPT_COMMAND='echo -ne "\e]0;$USER@${HOSTNAME}: $(pwd -P)\a"'
    

    The command for USER getting the current user is linux/gnu flags, MacOSX/bsd flags may differ.


  • Related Question

    linux - Show only current directory name (not full path) on bash prompt
  • obvio171

    The way my bash prompt is currently configured, it shows the whole path to the current directory. This is annoying when I'm deep inside a directory tree, as the prompt becomes so long that every command wraps into the next line. How do I make it show only the last part of the path?

    This is what I have in my .bashrc:

    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    
    # If this is an xterm set the title to user@host:dir
    case "$TERM" in
    xterm*|rxvt*)
        PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"'
        ;;
    *)
        ;;
    esac
    

  • Related Answers
  • quack quixote

    Change the \w (lowercase) to \W (uppercase):

    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ '
                                                                                           ^^
               this one waaaaaay over here ------------------------------------------------+
    

    Have a look at the Bash Prompt HOWTO for lots of fun details. example:

    user@host:/usr/local/bin$ echo $PS1
    ${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]\$ 
    
    user@host:/usr/local/bin$ export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\W\[\033[00m\]\$ '
    
    user@host:bin$
    

    The PROMPT_COMMAND variable, if set, is a command that gets run before displaying the prompt specified in PS1. In your case, PROMPT_COMMAND runs an echo statement with certain ANSI escape sequences that manipulate the titlebar of an Xterm.

    If you suspect your PROMPT_COMMAND is overriding your PS1 prompt, you can unset it and test things out:

    $ unset PROMPT_COMMAND
    

    Finally, be sure that you're changing the PS1 definition that actually gets used. Common locations are /etc/bash.bashrc, /etc/profile, ~/.bashrc, ~/.bash_profile, ~/.profile. The system files are generally (but not always) run before the user files.