Compact bash prompt when using a directory tree / filename
First of all, you might simply want to change the \w
with \W
. That way, only the name of the current directory is printed and not its entire path:
terdon@oregano:/home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name $ PS1="\u@\h:\W \$ "
terdon@oregano:my_actual_directory_with_another_long_name $
That might still not be enough if the directory name itself is too long. In that case, you can use the PROMPT_COMMAND
variable for this. This is a special bash variable whose value is executed as a command before each prompt is shown. So, if you set that to a function that sets your desired prompt based upon the length of your current directory's path, you can get the effect you're after. For example, add these lines to your ~/.bashrc
:
get_PS1(){
limit=${1:-20}
if [[ "${#PWD}" -gt "$limit" ]]; then
## Take the first 5 characters of the path
left="${PWD:0:5}"
## ${#PWD} is the length of $PWD. Get the last $limit
## characters of $PWD.
right="${PWD:$((${#PWD}-$limit)):${#PWD}}"
PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] ${left}...${right} \$\[\033[00m\] "
else
PS1="\[\033[01;33m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] "
fi
}
PROMPT_COMMAND=get_PS1
The effect looks like this:
terdon@oregano ~ $ cd /home/mydirectory1/second_directory_with_a_too_long_name/my_actual_directory_with_another_long_name
terdon@oregano /home...th_another_long_name $
Adding in a character return is my main solution to this
So my prompt (which has other stuff too, making it even longer) looks like this:
You'll notice that the $ is getting returned as a new line
I achieve this with
HOST='\[\033[02;36m\]\h'; HOST=' '$HOST
TIME='\[\033[01;31m\]\t \[\033[01;32m\]'
LOCATION=' \[\033[01;34m\]`pwd | sed "s#\(/[^/]\{1,\}/[^/]\{1,\}/[^/]\{1,\}/\).*\(/[^/]\{1,\}/[^/]\{1,\}\)/\{0,1\}#\1_\2#g"`'
PS1=$TIME$USER$HOST$LOCATION'\n\$ '
Note that, even though on a separate line, super long directory trees such as
/home/durrantm/Dropbox/96_2013_archive/work/code/ruby__rails
are shortened to
/home/durrantm/Dropbox/_/code/ruby__rails
i.e. "top 3 directories /_/ bottom two directories" which is usually what I care about
This will make sure that the line never gets too long due to directory tree length. If you always want the full directory tree just adjust LOCATION, i.e.
LOCATION=' \[\033[01;34m\]`pwd`'
Created ~/.bash_prompt:
maxlen=36
# set leftlen to zero for printing just the right part of the path
leftlen=19
shortened="..."
# Default PWD
nPWD=${PWD}
if [ ${#nPWD} -gt $maxlen ]; then
offset=$(( ${#nPWD} - $maxlen + $leftlen ))
nPWD="${nPWD:0:$leftlen}${shortened}${nPWD:$offset:$maxlen}"
else
nPWD='\w'
fi
echo "\u@\h:$nPWD\$ "
Added in my ~/.bash_profile:
function prompt_command {
export PS1=$(~/.bash_prompt)
}
export PROMPT_COMMAND=prompt_command
Output is:
user@machinename:/home/mydirectory1/...another_long_name$