1

Suppose I do a lot of work under the directory /home/user/documents/foo, so the Bash shell prompt could appear as follows:

user@hostname: ~/documents/foo/bar/baz $ 

My terminal is quite narrow, and the ~/documents/foo is not a helpful use of space, since I already know I am there.

I would therefore like my shell prompt to show the working directory relative to /home/user/documents/foo:

user@hostname: bar/baz $ 

The prompt is defined by the PS1 environment variable, and I can find ways of editing this to include the path relative to my user's home directory, or to include only the basename, but I can't seem to get a path relative to a different directory.

1
  • fwiw, I prefer to see the full path but like you I don't like all that real estate before the $ characters; I also prefer some white space separating prompts/command-output; solution: I embed a \n at the beginning of PS1 and before the $ characters, eg, PS1='\n\u@\h:${PWD}\n$ '; my actual PS1 is a bit more involved because I also prefer to use different colors for the \u@\h and ${PWD} strings, which has the benefit of making the prompt stand out from commands and output Commented Mar 4 at 18:23

2 Answers 2

1

From the bash manual:

PROMPT_DIRTRIM
If set to a number greater than zero, the value is used as the number of trailing directory components to retain when expanding the \w and \W prompt string escapes (see PROMPTING below). Characters removed are replaced with an ellipsis.

If your prompt string (PS1) uses \w or \W, you might want to use PROMPT_DIRTRIM=2.

myself@myhost:~$ echo $PS1 ${debian_chroot:+($debian_chroot)}\u@\h:\w\$ 
myself@myhost:~$ mkdir -p a/b/c/d/e myself@myhost:~$ cd a/b/c/d/e/ myself@myhost:~/a/b/c/d/e$ 
myself@myhost:~/a/b/c/d/e$ PROMPT_DIRTRIM=2 myself@myhost:~/.../d/e$ 
0

Zsh's %~ shortens any named directories similarly to $HOME is shortened in both zsh and Bash. But if you don't want to change shells, you can do it manually in Bash with something like this:

declare -A short_dirs=([~/documents/foo]=f [~]="~") shorten_dir() { local dir abbr shorter_dir="$PWD" for dir in "${!short_dirs[@]}"; do if [[ "$PWD" == "$dir"* ]]; then abbr="${short_dirs[$dir]}" shorter_dir="${PWD/$dir/[$abbr]}" return fi done } PROMPT_COMMAND=shorten_dir PS1='\u@\h $shorter_dir\$ ' 

Here, shorten_dirs() replaces the initial part of the working directory from $PWD and replaces it with an abbreviation if it matches any of the mappings in the associative array short_dirs. The function sets the shorter_dir variable that is used in the prompt itself. PROMPT_COMMAND calls the function before each prompt is printed.

In action, it looks something like this (starting from /):

me@foo /$ cd me@foo [~]$ cd documents/foo me@foo [f]$ cd bar/doo me@foo [f]/bar/doo$ 

That's not been extensively tested, though.

1
  • Just a nitpick, but it might be better to append to PROMPT_COMMAND instead of assigning, e.g., PROMPT_COMMAND="${PROMPT_COMMAND:-:};shorten_dir". Commented Mar 6 at 16:42

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.